diff --git a/botocore/exceptions.py b/botocore/exceptions.py index 9fa0dfaa84..25ed7fb90b 100644 --- a/botocore/exceptions.py +++ b/botocore/exceptions.py @@ -553,6 +553,31 @@ def __reduce__(self): # module. So at the very least return a ClientError back. return ClientError, (self.response, self.operation_name) + @property + def code(self): + """The error code returned by the AWS service.""" + return self.response.get('Error', {}).get('Code', 'Unknown') + + @property + def message(self): + """The error message returned by the AWS service.""" + return self.response.get('Error', {}).get('Message', 'Unknown') + + @property + def request_id(self): + """The request ID returned by the AWS service.""" + return self.response.get('ResponseMetadata').get('RequestId') + + @property + def http_status_code(self): + """The HTTP status code returned by the AWS service.""" + return self.response.get('ResponseMetadata', {}).get('HTTPStatusCode') + + @property + def http_headers(self): + """The HTTP headers returned by the AWS service.""" + return self.response.get('ResponseMetadata', {}).get('HTTPHeaders', {}) + class EventStreamError(ClientError): pass diff --git a/tests/unit/test_exceptions.py b/tests/unit/test_exceptions.py index 4d1c84c802..b0f41026a5 100644 --- a/tests/unit/test_exceptions.py +++ b/tests/unit/test_exceptions.py @@ -23,6 +23,17 @@ def test_client_error_can_handle_missing_code_or_message(): response = {'Error': {}} expect = 'An error occurred (Unknown) when calling the blackhole operation: Unknown' assert str(exceptions.ClientError(response, 'blackhole')) == expect + assert exceptions.ClientError.code == 'Unknown' + assert exceptions.ClientError.message == 'Unknown' + + +def test_client_error_can_handle_missing_response_metadata(): + response = {'Error': {}} + assert ( + exceptions.ClientError(response, 'blackhole').http_status_code is None + ) + assert exceptions.ClientError(response, 'blackhole').request_id is None + assert exceptions.ClientError(response, 'blackhole').http_headers == {} def test_client_error_has_operation_name_set():