From a56cac9aeb98d966be26db463ac3de692ee20601 Mon Sep 17 00:00:00 2001 From: hiranya911 Date: Thu, 29 Mar 2018 10:12:27 -0700 Subject: [PATCH 1/2] Reading FCM error code from details section --- firebase_admin/messaging.py | 14 ++++++++++---- tests/test_messaging.py | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/firebase_admin/messaging.py b/firebase_admin/messaging.py index b07548473..c18616bf2 100644 --- a/firebase_admin/messaging.py +++ b/firebase_admin/messaging.py @@ -816,10 +816,16 @@ def _handle_fcm_error(self, error): except ValueError: pass - error_details = data.get('error', {}) - code = _MessagingService.FCM_ERROR_CODES.get( - error_details.get('status'), _MessagingService.UNKNOWN_ERROR) - msg = error_details.get('message') + error_dict = data.get('error', {}) + server_code = None + for detail in error_dict.get('details', []): + if detail.get('@type') == 'type.googleapis.com/google.firebase.fcm.v1.FcmErrorCode': + server_code = detail.get('errorCode') + if not server_code: + server_code = error_dict.get('status') + code = _MessagingService.FCM_ERROR_CODES.get(server_code, _MessagingService.UNKNOWN_ERROR) + + msg = error_dict.get('message') if not msg: msg = 'Unexpected HTTP response with status: {0}; body: {1}'.format( error.response.status_code, error.response.content.decode()) diff --git a/tests/test_messaging.py b/tests/test_messaging.py index ffd18a88f..5d0166619 100644 --- a/tests/test_messaging.py +++ b/tests/test_messaging.py @@ -914,6 +914,32 @@ def test_send_canonical_error_code(self, status): body = {'message': messaging._MessagingService.JSON_ENCODER.default(msg)} assert json.loads(recorder[0].body.decode()) == body + @pytest.mark.parametrize('status', HTTP_ERRORS) + def test_send_fcm_error_code(self, status): + payload = json.dumps({ + 'error': { + 'status': 'INVALID_ARGUMENT', + 'message': 'test error', + 'details': [ + { + '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmErrorCode', + 'errorCode': 'UNREGISTERED', + }, + ], + } + }) + _, recorder = self._instrument_messaging_service(status=status, payload=payload) + msg = messaging.Message(topic='foo') + with pytest.raises(messaging.ApiCallError) as excinfo: + messaging.send(msg) + assert str(excinfo.value) == 'test error' + assert str(excinfo.value.code) == 'registration-token-not-registered' + assert len(recorder) == 1 + assert recorder[0].method == 'POST' + assert recorder[0].url == self._get_url('explicit-project-id') + body = {'message': messaging._MessagingService.JSON_ENCODER.default(msg)} + assert json.loads(recorder[0].body.decode()) == body + class TestTopicManagement(object): From 2a01e7cbd1c1addf6a30e628bbff9e9b4be07068 Mon Sep 17 00:00:00 2001 From: hiranya911 Date: Thu, 29 Mar 2018 10:27:55 -0700 Subject: [PATCH 2/2] Early terminating the loop --- firebase_admin/messaging.py | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase_admin/messaging.py b/firebase_admin/messaging.py index c18616bf2..299cc6058 100644 --- a/firebase_admin/messaging.py +++ b/firebase_admin/messaging.py @@ -821,6 +821,7 @@ def _handle_fcm_error(self, error): for detail in error_dict.get('details', []): if detail.get('@type') == 'type.googleapis.com/google.firebase.fcm.v1.FcmErrorCode': server_code = detail.get('errorCode') + break if not server_code: server_code = error_dict.get('status') code = _MessagingService.FCM_ERROR_CODES.get(server_code, _MessagingService.UNKNOWN_ERROR)