Skip to content

Commit 273b058

Browse files
authored
fix(fcm): Converting unexpected gapic runtime errors to FirebaseError (#509)
1 parent 2b8cb45 commit 273b058

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

firebase_admin/messaging.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import json
1818

19-
import googleapiclient
2019
from googleapiclient import http
2120
from googleapiclient import _auth
2221
import requests
@@ -388,7 +387,7 @@ def batch_callback(_, response, error):
388387

389388
try:
390389
batch.execute()
391-
except googleapiclient.http.HttpError as error:
390+
except Exception as error:
392391
raise self._handle_batch_error(error)
393392
else:
394393
return BatchResponse(responses)

tests/test_messaging.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,15 @@ def test_send_unknown_fcm_error_code(self, status):
17921792
assert json.loads(recorder[0].body.decode()) == body
17931793

17941794

1795+
class _HttpMockException:
1796+
1797+
def __init__(self, exc):
1798+
self._exc = exc
1799+
1800+
def request(self, url, **kwargs):
1801+
raise self._exc
1802+
1803+
17951804
class TestBatch:
17961805

17971806
@classmethod
@@ -1803,17 +1812,21 @@ def setup_class(cls):
18031812
def teardown_class(cls):
18041813
testutils.cleanup_apps()
18051814

1806-
def _instrument_batch_messaging_service(self, app=None, status=200, payload=''):
1815+
def _instrument_batch_messaging_service(self, app=None, status=200, payload='', exc=None):
18071816
if not app:
18081817
app = firebase_admin.get_app()
1818+
18091819
fcm_service = messaging._get_messaging_service(app)
1810-
if status == 200:
1811-
content_type = 'multipart/mixed; boundary=boundary'
1820+
if exc:
1821+
fcm_service._transport = _HttpMockException(exc)
18121822
else:
1813-
content_type = 'application/json'
1814-
fcm_service._transport = http.HttpMockSequence([
1815-
({'status': str(status), 'content-type': content_type}, payload),
1816-
])
1823+
if status == 200:
1824+
content_type = 'multipart/mixed; boundary=boundary'
1825+
else:
1826+
content_type = 'application/json'
1827+
fcm_service._transport = http.HttpMockSequence([
1828+
({'status': str(status), 'content-type': content_type}, payload),
1829+
])
18171830
return fcm_service
18181831

18191832
def _batch_payload(self, payloads):
@@ -2027,6 +2040,19 @@ def test_send_all_batch_fcm_error_code(self, status):
20272040
messaging.send_all([msg])
20282041
check_exception(excinfo.value, 'test error', status)
20292042

2043+
def test_send_all_runtime_exception(self):
2044+
exc = BrokenPipeError('Test error')
2045+
_ = self._instrument_batch_messaging_service(exc=exc)
2046+
msg = messaging.Message(topic='foo')
2047+
2048+
with pytest.raises(exceptions.UnknownError) as excinfo:
2049+
messaging.send_all([msg])
2050+
2051+
expected = 'Unknown error while making a remote service call: Test error'
2052+
assert str(excinfo.value) == expected
2053+
assert excinfo.value.cause is exc
2054+
assert excinfo.value.http_response is None
2055+
20302056

20312057
class TestSendMulticast(TestBatch):
20322058

@@ -2204,6 +2230,19 @@ def test_send_multicast_batch_fcm_error_code(self, status):
22042230
messaging.send_multicast(msg)
22052231
check_exception(excinfo.value, 'test error', status)
22062232

2233+
def test_send_multicast_runtime_exception(self):
2234+
exc = BrokenPipeError('Test error')
2235+
_ = self._instrument_batch_messaging_service(exc=exc)
2236+
msg = messaging.MulticastMessage(tokens=['foo'])
2237+
2238+
with pytest.raises(exceptions.UnknownError) as excinfo:
2239+
messaging.send_multicast(msg)
2240+
2241+
expected = 'Unknown error while making a remote service call: Test error'
2242+
assert str(excinfo.value) == expected
2243+
assert excinfo.value.cause is exc
2244+
assert excinfo.value.http_response is None
2245+
22072246

22082247
class TestTopicManagement:
22092248

0 commit comments

Comments
 (0)