From b855365ef0aa77924ec7a39952bc3ebdd1922f97 Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Mon, 15 Aug 2022 17:10:21 -0700 Subject: [PATCH] Capture requests errors Situations can occur where rare exceptions can originate from within python requests, which are not captured or handled in Sushy. Example: Encoding errors should trigger some sort of recovery, but cached session clients cannot recover, and power synchronization for users, such as Ironic, break on the cached session when they attempt to access them for the same task, again. Change-Id: I0f79083d41b0b7ccf7e4dbfc81fd1d42c2e5eb15 --- ...-requests-exceptions-b5fd706597708fb6.yaml | 8 ++++++++ sushy/connector.py | 9 ++++++++- sushy/tests/unit/test_connector.py | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/catch-general-requests-exceptions-b5fd706597708fb6.yaml diff --git a/releasenotes/notes/catch-general-requests-exceptions-b5fd706597708fb6.yaml b/releasenotes/notes/catch-general-requests-exceptions-b5fd706597708fb6.yaml new file mode 100644 index 00000000..ae7ff8d7 --- /dev/null +++ b/releasenotes/notes/catch-general-requests-exceptions-b5fd706597708fb6.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixes potential cases where exceptions from the underlying ``requests`` + library may be raised up through ``sushy``, resulting in client + applications possibly not understanding that an error has occurred. + The sushy ``ConnectionError`` exception is now returned upon any exception + falling under ``RequestException`` from the ``requests`` library. diff --git a/sushy/connector.py b/sushy/connector.py index c56fcd6e..7cb32a71 100644 --- a/sushy/connector.py +++ b/sushy/connector.py @@ -125,7 +125,14 @@ class Connector(object): response = self._session.request(method, url, json=data, headers=headers, **extra_session_req_kwargs) - except requests.ConnectionError as e: + except requests.exceptions.RequestException as e: + # Capture any general exception by looking for the parent + # class of exceptions in the requests library. + # Specifically this will cover cases such as transport + # failures, connection timeouts, and encoding errors. + # Raising this as sushy ConnectionError allows users to + # understand something bad has happened, and to + # allow them to respond accordingly. raise exceptions.ConnectionError(url=url, error=e) if self._response_callback: diff --git a/sushy/tests/unit/test_connector.py b/sushy/tests/unit/test_connector.py index 5398619d..958e4d25 100644 --- a/sushy/tests/unit/test_connector.py +++ b/sushy/tests/unit/test_connector.py @@ -558,3 +558,22 @@ class ConnectorOpTestCase(base.TestCase): 'returned code HTTPStatus.FORBIDDEN. unknown error ' 'Extended information: none'} ) + + def test__op_raises_connection_error(self): + + exception_list = [ + requests.exceptions.ChunkedEncodingError, + requests.exceptions.ContentDecodingError, + requests.exceptions.ReadTimeout, + requests.exceptions.ConnectTimeout, + requests.exceptions.SSLError, + requests.exceptions.ConnectionError, + requests.exceptions.RequestException, + ] + for exc in exception_list: + self.request.side_effect = exc + self.assertRaises(exceptions.ConnectionError, + self.conn._op, + 'POST', + 'http://foo.bar', + blocking=True)