From 8a828b2baa2eefb9467e08bb6ab79d8dc9e22a3b Mon Sep 17 00:00:00 2001 From: Gregory Mulholland Date: Wed, 25 Mar 2026 12:02:07 -0700 Subject: [PATCH] Fix silent error swallowing in session error handling - Replace silent ValueError pass with logger.debug for 401 JSON parsing (was completely invisible to users/developers) - Downgrade AttributeError from logger.error to logger.debug (this is an expected case, not a true error) - Upgrade JSONDecodeError in _extract_response_json from logger.info to logger.warning (returning empty dict silently can cause confusing downstream failures) Co-Authored-By: Claude Opus 4.6 (1M context) --- src/citrine/_session.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/citrine/_session.py b/src/citrine/_session.py index c403a574b..36357868b 100644 --- a/src/citrine/_session.py +++ b/src/citrine/_session.py @@ -171,13 +171,13 @@ def checked_request(self, method: str, path: str, self._refresh_access_token() response = self._request_with_retry(method, uri, **kwargs) except AttributeError: - # Catch AttributeErrors and log response - # The 401 status will be handled further down - logger.error("Failed to decode json from response: {}".format(response.text)) + # json() returned non-dict (e.g. list/string); 401 handled below + logger.debug("Response JSON is not a dict (status %s): %s", + response.status_code, response.text[:200]) except ValueError: - # Ignore ValueErrors thrown by attempting to decode json bodies. This - # might occur if we get a 401 response without a JSON body - pass + # Response has no JSON body (common for 401); 401 handled below + logger.debug("Response with status %s has no JSON body", + response.status_code) if 200 <= response.status_code <= 299: logger.info('%s %s %s', response.status_code, method, path) @@ -258,11 +258,11 @@ def _extract_response_json(path, response) -> dict: lacked the required 'application/json' Content-Type in the header.""") except JSONDecodeError as err: - logger.info('Response at path %s with status code %s failed json parsing with' - ' exception %s. Returning empty value.', - path, - response.status_code, - err.msg) + logger.warning( + 'Response at path %s with status code %s failed JSON ' + 'parsing (%s). Returning empty dict — downstream code ' + 'may behave unexpectedly.', + path, response.status_code, err.msg) return extracted_response