Skip to content

Commit

Permalink
Merge pull request #92 from web-push-libs/bug/90
Browse files Browse the repository at this point in the history
bug: return the remote server response in the WebpushException
  • Loading branch information
jrconlin committed Apr 2, 2018
2 parents 13e747d + 5e81898 commit aa66fde
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 10 deletions.
10 changes: 9 additions & 1 deletion README.md
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion README.rst
Expand Up @@ -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
~~~~~~~
Expand Down
32 changes: 26 additions & 6 deletions pywebpush/__init__.py
Expand Up @@ -21,7 +21,26 @@


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):
Expand Down Expand Up @@ -371,15 +390,16 @@ 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,
content_encoding=content_encoding,
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
31 changes: 30 additions & 1 deletion pywebpush/tests/test_webpush.py
Expand Up @@ -3,7 +3,7 @@
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
Expand Down Expand Up @@ -339,3 +339,32 @@ def test_send_using_requests_session(self, mock_session):
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]"
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -3,7 +3,7 @@

from setuptools import find_packages, setup

__version__ = "1.6.0"
__version__ = "1.7.0"


def read_from(file):
Expand Down

0 comments on commit aa66fde

Please sign in to comment.