Skip to content

Commit aa66fde

Browse files
authored
Merge pull request #92 from web-push-libs/bug/90
bug: return the remote server response in the WebpushException
2 parents 13e747d + 5e81898 commit aa66fde

File tree

5 files changed

+75
-10
lines changed

5 files changed

+75
-10
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ in the `subscription_info` block.
6565
*data* - can be any serial content (string, bit array, serialized JSON, etc), but be sure that your receiving
6666
application is able to parse and understand it. (e.g. `data = "Mary had a little lamb."`)
6767

68-
*content_type* - specifies the form of Encryption to use, either `'aesgcm'` or the newer `'aes128gcm'`. NOTE that
68+
*content_type* - specifies the form of Encryption to use, either `'aesgcm'` or the newer `'aes128gcm'`. NOTE that
6969
not all User Agents can decrypt `'aes128gcm'`, so the library defaults to the older form.
7070

7171
*vapid_claims* - a `dict` containing the VAPID claims required for authorization (See
@@ -103,6 +103,14 @@ try:
103103
)
104104
except WebPushException as ex:
105105
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
106+
# Mozilla returns additional information in the body of the response.
107+
if ex.response and ex.response.json():
108+
extra = ex.response.json()
109+
print("Remote service replied with a {}:{}, {}",
110+
extra.code,
111+
extra.errno,
112+
extra.message
113+
)
106114
```
107115

108116
### Methods

README.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,19 @@ e.g. the output of:
105105
data="Mary had a little lamb, with a nice mint jelly",
106106
vapid_private_key="path/to/vapid_private.pem",
107107
vapid_claims={
108-
108+
"sub": "mailto:[email protected]",
109109
}
110110
)
111111
except WebPushException as ex:
112112
print("I'm sorry, Dave, but I can't do that: {}", repr(ex))
113+
# Mozilla returns additional information in the body of the response.
114+
if ex.response and ex.response.json():
115+
extra = ex.response.json()
116+
print("Remote service replied with a {}:{}, {}",
117+
extra.code,
118+
extra.errno,
119+
extra.message
120+
)
113121
114122
Methods
115123
~~~~~~~

pywebpush/__init__.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,26 @@
2121

2222

2323
class WebPushException(Exception):
24-
pass
24+
"""Web Push failure.
25+
26+
This may contain the requests.Response
27+
28+
"""
29+
30+
def __init__(self, message, response=None):
31+
self.message = message
32+
self.response = response
33+
34+
def __str__(self):
35+
extra = ""
36+
if self.response:
37+
try:
38+
extra = ", Response {}".format(
39+
self.response.text,
40+
)
41+
except AttributeError:
42+
extra = ", Response {}".format(self.response)
43+
return "WebPushException: {}{}".format(self.message, extra)
2544

2645

2746
class CaseInsensitiveDict(dict):
@@ -371,15 +390,16 @@ def webpush(subscription_info,
371390
else:
372391
vv = Vapid.from_string(private_key=vapid_private_key)
373392
vapid_headers = vv.sign(vapid_claims)
374-
result = WebPusher(subscription_info).send(
393+
response = WebPusher(subscription_info).send(
375394
data,
376395
vapid_headers,
377396
ttl=ttl,
378397
content_encoding=content_encoding,
379398
curl=curl,
380399
timeout=timeout,
381400
)
382-
if not curl and result.status_code > 202:
383-
raise WebPushException("Push failed: {}: {}".format(
384-
result, result.text))
385-
return result
401+
if not curl and response.status_code > 202:
402+
raise WebPushException("Push failed: {} {}".format(
403+
response.status_code, response.reason),
404+
response=response)
405+
return response

pywebpush/tests/test_webpush.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import unittest
55

6-
from mock import patch
6+
from mock import patch, Mock
77
from nose.tools import eq_, ok_, assert_is_not, assert_raises
88
import http_ece
99
from cryptography.hazmat.primitives.asymmetric import ec
@@ -339,3 +339,32 @@ def test_send_using_requests_session(self, mock_session):
339339
ckey = pheaders.get('crypto-key')
340340
ok_('pre-existing' in ckey)
341341
eq_(pheaders.get('content-encoding'), 'aesgcm')
342+
343+
344+
class WebpushExceptionTestCase(unittest.TestCase):
345+
346+
def test_exception(self):
347+
from requests import Response
348+
349+
exp = WebPushException("foo")
350+
assert ("{}".format(exp) == "WebPushException: foo")
351+
# Really should try to load the response to verify, but this mock
352+
# covers what we need.
353+
response = Mock(spec=Response)
354+
response.text = (
355+
'{"code": 401, "errno": 109, "error": '
356+
'"Unauthorized", "more_info": "http://'
357+
'autopush.readthedocs.io/en/latest/htt'
358+
'p.html#error-codes", "message": "Requ'
359+
'est did not validate missing authoriz'
360+
'ation header"}')
361+
response.json.return_value = json.loads(response.text)
362+
response.status_code = 401
363+
response.reason = "Unauthorized"
364+
exp = WebPushException("foo", response)
365+
assert "{}".format(exp) == "WebPushException: foo, Response {}".format(
366+
response.text)
367+
assert '{}'.format(exp.response), '<Response [401]>'
368+
assert exp.response.json().get('errno') == 109
369+
exp = WebPushException("foo", [1, 2, 3])
370+
assert '{}'.format(exp) == "WebPushException: foo, Response [1, 2, 3]"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from setuptools import find_packages, setup
55

6-
__version__ = "1.6.0"
6+
__version__ = "1.7.0"
77

88

99
def read_from(file):

0 commit comments

Comments
 (0)