diff --git a/dapr/clients/exceptions.py b/dapr/clients/exceptions.py index 70468553..6e617175 100644 --- a/dapr/clients/exceptions.py +++ b/dapr/clients/exceptions.py @@ -72,6 +72,9 @@ def __init__(self, err: RpcError): self._parse_details() def _parse_details(self): + if self._grpc_status is None: + return + for detail in self._grpc_status.details: if detail.Is(error_details_pb2.ErrorInfo.DESCRIPTOR): self._details.error_info = serialize_status_detail(detail) @@ -95,13 +98,17 @@ def _parse_details(self): self._details.localized_message = serialize_status_detail(detail) def code(self): - return self._status_code.name + return self._status_code - def message(self): + def details(self): + """ + We're keeping the method name details() so it matches the grpc.RpcError interface. + @return: + """ return self._err_message def error_code(self): - if not self._details.error_info: + if not self.status_details() or not self.status_details().error_info: return ERROR_CODE_UNKNOWN return self._details.error_info['reason'] @@ -114,7 +121,7 @@ def get_grpc_status(self): def json(self): error_details = { 'status_code': self.code(), - 'message': self.message(), + 'message': self.details(), 'error_code': self.error_code(), 'details': self._details.as_dict(), } diff --git a/dev-requirements.txt b/dev-requirements.txt index 3401b39c..bf648667 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,4 +1,3 @@ -grpcio-status>=1.60.0 mypy>=1.2.0 mypy-extensions>=0.4.3 mypy-protobuf>=2.9 diff --git a/examples/error_handling/error_handling.py b/examples/error_handling/error_handling.py index 8d26b522..609e46b1 100644 --- a/examples/error_handling/error_handling.py +++ b/examples/error_handling/error_handling.py @@ -17,21 +17,22 @@ print(f'Status code: {err.code()}', flush=True) print(f'Message: {err.message()}', flush=True) print(f'Error code: {err.error_code()}', flush=True) - print(f'Error info(reason): {err.status_details().error_info["reason"]}', flush=True) - print( - f'Resource info (resource type): {err.status_details().resource_info["resource_type"]}', - flush=True, - ) - print( - f'Resource info (resource name): {err.status_details().resource_info["resource_name"]}', - flush=True, - ) - print( - f'Bad request (field): {err.status_details().bad_request["field_violations"][0]["field"]}', - flush=True, - ) - print( - f'Bad request (description): {err.status_details().bad_request["field_violations"][0]["description"]}', - flush=True, - ) - print(f'JSON: {err.json()}', flush=True) + if err.status_details() is not None: + print(f'Error info(reason): {err.status_details().error_info["reason"]}', flush=True) + print( + f'Resource info (resource type): {err.status_details().resource_info["resource_type"]}', + flush=True, + ) + print( + f'Resource info (resource name): {err.status_details().resource_info["resource_name"]}', + flush=True, + ) + print( + f'Bad request (field): {err.status_details().bad_request["field_violations"][0]["field"]}', + flush=True, + ) + print( + f'Bad request (description): {err.status_details().bad_request["field_violations"][0]["description"]}', + flush=True, + ) + print(f'JSON: {err.json()}', flush=True) diff --git a/tests/clients/test_exceptions.py b/tests/clients/test_exceptions.py index 14e64f5b..d6f2890a 100644 --- a/tests/clients/test_exceptions.py +++ b/tests/clients/test_exceptions.py @@ -107,8 +107,8 @@ def test_exception_status_parsing(self): dapr_error = context.exception - self.assertEqual(dapr_error.code(), 'INTERNAL') - self.assertEqual(dapr_error.message(), 'my invalid argument message') + self.assertEqual(dapr_error.code(), grpc.StatusCode.INTERNAL) + self.assertEqual(dapr_error.details(), 'my invalid argument message') self.assertEqual(dapr_error.error_code(), 'DAPR_ERROR_CODE') self.assertIsNotNone(dapr_error._details.error_info)