diff --git a/firebase_admin/_utils.py b/firebase_admin/_utils.py index fb6e32932..35a1b7467 100644 --- a/firebase_admin/_utils.py +++ b/firebase_admin/_utils.py @@ -58,6 +58,25 @@ 503: exceptions.UNAVAILABLE, } +# See https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto +_RPC_CODE_TO_ERROR_CODE = { + 1: exceptions.CANCELLED, + 2: exceptions.UNKNOWN, + 3: exceptions.INVALID_ARGUMENT, + 4: exceptions.DEADLINE_EXCEEDED, + 5: exceptions.NOT_FOUND, + 6: exceptions.ALREADY_EXISTS, + 7: exceptions.PERMISSION_DENIED, + 8: exceptions.RESOURCE_EXHAUSTED, + 9: exceptions.FAILED_PRECONDITION, + 10: exceptions.ABORTED, + 11: exceptions.OUT_OF_RANGE, + 13: exceptions.INTERNAL, + 14: exceptions.UNAVAILABLE, + 15: exceptions.DATA_LOSS, + 16: exceptions.UNAUTHENTICATED, +} + def _get_initialized_app(app): if app is None: @@ -120,9 +139,9 @@ def handle_operation_error(error): message='Unknown error while making a remote service call: {0}'.format(error), cause=error) - status_code = error.get('code') + rpc_code = error.get('code') message = error.get('message') - error_code = _http_status_to_error_code(status_code) + error_code = _rpc_code_to_error_code(rpc_code) err_type = _error_code_to_exception_type(error_code) return err_type(message=message) @@ -283,6 +302,9 @@ def _http_status_to_error_code(status): """Maps an HTTP status to a platform error code.""" return _HTTP_STATUS_TO_ERROR_CODE.get(status, exceptions.UNKNOWN) +def _rpc_code_to_error_code(rpc_code): + """Maps an RPC code to a platform error code.""" + return _RPC_CODE_TO_ERROR_CODE.get(rpc_code, exceptions.UNKNOWN) def _error_code_to_exception_type(code): """Maps a platform error code to an exception type.""" diff --git a/requirements.txt b/requirements.txt index 7a8d855bd..c89318a67 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ pytest-cov >= 2.4.0 pytest-localserver >= 0.4.1 tox >= 3.6.0 -cachecontrol >= 0.12.4 +cachecontrol >= 0.12.6 google-api-core[grpc] >= 1.7.0, < 2.0.0dev; platform.python_implementation != 'PyPy' google-api-python-client >= 1.7.8 google-cloud-firestore >= 0.31.0; platform.python_implementation != 'PyPy' diff --git a/setup.py b/setup.py index 15ae97f93..c463108d0 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ long_description = ('The Firebase Admin Python SDK enables server-side (backend) Python developers ' 'to integrate Firebase into their services and applications.') install_requires = [ - 'cachecontrol>=0.12.4', + 'cachecontrol>=0.12.6', 'google-api-core[grpc] >= 1.7.0, < 2.0.0dev; platform.python_implementation != "PyPy"', 'google-api-python-client >= 1.7.8', 'google-cloud-firestore>=0.31.0; platform.python_implementation != "PyPy"', diff --git a/tests/test_db.py b/tests/test_db.py index 081c31e3d..e9f8f7dda 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -819,7 +819,7 @@ def test_http_timeout(self): assert ref._client.timeout == 60 assert ref.get() == {} assert len(recorder) == 1 - assert recorder[0]._extra_kwargs['timeout'] == 60 + assert recorder[0]._extra_kwargs['timeout'] == pytest.approx(60, 0.001) def test_app_delete(self): app = firebase_admin.initialize_app( diff --git a/tests/test_messaging.py b/tests/test_messaging.py index 40f6baada..5d048d613 100644 --- a/tests/test_messaging.py +++ b/tests/test_messaging.py @@ -1254,7 +1254,7 @@ def test_send(self): msg = messaging.Message(topic='foo') messaging.send(msg) assert len(self.recorder) == 1 - assert self.recorder[0]._extra_kwargs['timeout'] == 4 + assert self.recorder[0]._extra_kwargs['timeout'] == pytest.approx(4, 0.001) def test_topic_management_timeout(self): self.fcm_service._client.session.mount( @@ -1266,7 +1266,7 @@ def test_topic_management_timeout(self): ) messaging.subscribe_to_topic(['1'], 'a') assert len(self.recorder) == 1 - assert self.recorder[0]._extra_kwargs['timeout'] == 4 + assert self.recorder[0]._extra_kwargs['timeout'] == pytest.approx(4, 0.001) class TestSend(object): diff --git a/tests/test_ml.py b/tests/test_ml.py index e66507e88..18aa789f8 100644 --- a/tests/test_ml.py +++ b/tests/test_ml.py @@ -169,7 +169,7 @@ # Name is required if the operation is not done. 'done': False } -OPERATION_ERROR_CODE = 400 +OPERATION_ERROR_CODE = 3 OPERATION_ERROR_MSG = "Invalid argument" OPERATION_ERROR_EXPECTED_STATUS = 'INVALID_ARGUMENT' OPERATION_ERROR_JSON_1 = {