bug: return the remote server response in the WebpushException

Closes #90
This commit is contained in:
jrconlin 2018-03-30 10:28:39 -07:00
parent 9875a4b481
commit 3fe08ad1e6
5 changed files with 75 additions and 10 deletions

View File

@ -65,7 +65,7 @@ in the `subscription_info` block.
*data* - can be any serial content (string, bit array, serialized JSON, etc), but be sure that your receiving
application is able to parse and understand it. (e.g. `data = "Mary had a little lamb."`)
*content_type* - specifies the form of Encryption to use, either `'aesgcm'` or the newer `'aes128gcm'`. NOTE that
*content_type* - specifies the form of Encryption to use, either `'aesgcm'` or the newer `'aes128gcm'`. NOTE that
not all User Agents can decrypt `'aes128gcm'`, so the library defaults to the older form.
*vapid_claims* - a `dict` containing the VAPID claims required for authorization (See
@ -103,6 +103,14 @@ try:
)
except WebPushException as ex:
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
# Mozilla returns additional information in the body of the response.
if ex.response and ex.response.json():
extra = ex.response.json()
print("Remote service replied with a {}:{}, {}",
extra.code,
extra.errno,
extra.message
)
```
### Methods

View File

@ -105,11 +105,19 @@ e.g. the output of:
data="Mary had a little lamb, with a nice mint jelly",
vapid_private_key="path/to/vapid_private.pem",
vapid_claims={
"sub": "YourNameHere@example.org",
"sub": "mailto:YourNameHere@example.org",
}
)
except WebPushException as ex:
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
# Mozilla returns additional information in the body of the response.
if ex.response and ex.response.json():
extra = ex.response.json()
print("Remote service replied with a {}:{}, {}",
extra.code,
extra.errno,
extra.message
)
Methods
~~~~~~~

View File

@ -21,7 +21,26 @@ from py_vapid import Vapid
class WebPushException(Exception):
pass
"""Web Push failure.
This may contain the requests.Response
"""
def __init__(self, message, response=None):
self.message = message
self.response = response
def __str__(self):
extra = ""
if self.response:
try:
extra = ", Response {}".format(
self.response.text,
)
except AttributeError:
extra = ", Response {}".format(self.response)
return "WebPushException: {}{}".format(self.message, extra)
class CaseInsensitiveDict(dict):
@ -371,7 +390,7 @@ def webpush(subscription_info,
else:
vv = Vapid.from_string(private_key=vapid_private_key)
vapid_headers = vv.sign(vapid_claims)
result = WebPusher(subscription_info).send(
response = WebPusher(subscription_info).send(
data,
vapid_headers,
ttl=ttl,
@ -379,7 +398,8 @@ def webpush(subscription_info,
curl=curl,
timeout=timeout,
)
if not curl and result.status_code > 202:
raise WebPushException("Push failed: {}: {}".format(
result, result.text))
return result
if not curl and response.status_code > 202:
raise WebPushException("Push failed: {} {}".format(
response.status_code, response.reason),
response=response)
return response

View File

@ -3,7 +3,7 @@ import json
import os
import unittest
from mock import patch
from mock import patch, Mock
from nose.tools import eq_, ok_, assert_is_not, assert_raises
import http_ece
from cryptography.hazmat.primitives.asymmetric import ec
@ -339,3 +339,32 @@ class WebpushTestCase(unittest.TestCase):
ckey = pheaders.get('crypto-key')
ok_('pre-existing' in ckey)
eq_(pheaders.get('content-encoding'), 'aesgcm')
class WebpushExceptionTestCase(unittest.TestCase):
def test_exception(self):
from requests import Response
exp = WebPushException("foo")
assert ("{}".format(exp) == "WebPushException: foo")
# Really should try to load the response to verify, but this mock
# covers what we need.
response = Mock(spec=Response)
response.text = (
'{"code": 401, "errno": 109, "error": '
'"Unauthorized", "more_info": "http://'
'autopush.readthedocs.io/en/latest/htt'
'p.html#error-codes", "message": "Requ'
'est did not validate missing authoriz'
'ation header"}')
response.json.return_value = json.loads(response.text)
response.status_code = 401
response.reason = "Unauthorized"
exp = WebPushException("foo", response)
assert "{}".format(exp) == "WebPushException: foo, Response {}".format(
response.text)
assert '{}'.format(exp.response), '<Response [401]>'
assert exp.response.json().get('errno') == 109
exp = WebPushException("foo", [1, 2, 3])
assert '{}'.format(exp) == "WebPushException: foo, Response [1, 2, 3]"

View File

@ -3,7 +3,7 @@ import os
from setuptools import find_packages, setup
__version__ = "1.6.0"
__version__ = "1.7.0"
def read_from(file):