From 0f6713ed5b8cdcf5cbc0850dea224b41d90e63f4 Mon Sep 17 00:00:00 2001 From: Tim Burke Date: Fri, 14 Aug 2020 10:41:15 -0700 Subject: [PATCH] Include transaction ID in ClientException.__str__ It's fairly annoying getting a traceback in swift's probe tests then only having a URL and status code to go searching for in logs. Leave the shell.py output untouched, though, since we output the transaction ID on a new line anyway. Change-Id: Idb849848ec08b6c04812b088467c9a687c2a7e27 --- swiftclient/exceptions.py | 12 +++++++++++- swiftclient/shell.py | 3 ++- test/unit/test_swiftclient.py | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/swiftclient/exceptions.py b/swiftclient/exceptions.py index da70379e..a9b993ce 100644 --- a/swiftclient/exceptions.py +++ b/swiftclient/exceptions.py @@ -35,6 +35,13 @@ class ClientException(Exception): self.http_response_content = http_response_content self.http_response_headers = http_response_headers + self.transaction_id = None + if self.http_response_headers: + for header in ('X-Trans-Id', 'X-Openstack-Request-Id'): + if header in self.http_response_headers: + self.transaction_id = self.http_response_headers[header] + break + @classmethod def from_response(cls, resp, msg=None, body=None): msg = msg or '%s %s' % (resp.status_code, resp.reason) @@ -78,4 +85,7 @@ class ClientException(Exception): else: b += ' [first 60 chars of response] %s' \ % self.http_response_content[:60] - return b and '%s: %s' % (a, b) or a + c = '' + if self.transaction_id: + c = ' (txn: %s)' % self.transaction_id + return b and '%s: %s%s' % (a, b, c) or (a + c) diff --git a/swiftclient/shell.py b/swiftclient/shell.py index b129d637..dbcd437b 100755 --- a/swiftclient/shell.py +++ b/swiftclient/shell.py @@ -2058,8 +2058,9 @@ Examples: try: globals()['st_%s' % args[0]](parser, argv[1:], output) except ClientException as err: + trans_id = err.transaction_id + err.transaction_id = None # clear it so we aren't overly noisy output.error(str(err)) - trans_id = (err.http_response_headers or {}).get('X-Trans-Id') if trans_id: output.error("Failed Transaction ID: %s", parse_header_string(trans_id)) diff --git a/test/unit/test_swiftclient.py b/test/unit/test_swiftclient.py index dfd79c77..2644e337 100644 --- a/test/unit/test_swiftclient.py +++ b/test/unit/test_swiftclient.py @@ -84,6 +84,23 @@ class TestClientException(unittest.TestCase): self.assertIs(True, hasattr(exc, key)) self.assertEqual(getattr(exc, key), value) + def test_transaction_id_from_headers(self): + exc = c.ClientException('test') + self.assertIsNone(exc.transaction_id) + + exc = c.ClientException('test', http_response_headers={}) + self.assertIsNone(exc.transaction_id) + + exc = c.ClientException('test', http_response_headers={ + 'X-Trans-Id': 'some-id'}) + self.assertEqual(exc.transaction_id, 'some-id') + self.assertIn('(txn: some-id)', str(exc)) + + exc = c.ClientException('test', http_response_headers={ + 'X-Openstack-Request-Id': 'some-other-id'}) + self.assertEqual(exc.transaction_id, 'some-other-id') + self.assertIn('(txn: some-other-id)', str(exc)) + class MockHttpResponse(object): def __init__(self, status=0, headers=None, verify=False):