Narrow exception scope lending#12220
Narrow exception scope lending#12220Arnav-0206 wants to merge 3 commits intointernetarchive:masterfrom
Conversation
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Pull request overview
Refactors openlibrary/core/lending.py to narrow previously broad exception handling around IA/network calls and JSON parsing, aligning behavior with the intent of existing TODOs while avoiding swallowing unrelated errors.
Changes:
- Replaced several
except Exceptionblocks with targeted network/JSON exceptions (httpx.HTTPError,requests.RequestException,JSONDecodeError). - Removed corresponding TODO comments where the exception scope was narrowed.
- Kept the broad exception in
sync_loan()intentionally.
| except (httpx.HTTPError, JSONDecodeError): | ||
| logger.exception(f"get_loan({identifier}) 2 of 2") |
There was a problem hiding this comment.
Same as the prior except: if .json() fails for the IA loan lookup, httpx will commonly raise ValueError/json.JSONDecodeError rather than simplejson.errors.JSONDecodeError. Consider extending the caught decode exception types here too so malformed JSON is handled consistently.
| except (httpx.HTTPError, JSONDecodeError): | ||
| logger.exception(f"get_available({url})") | ||
| return {'error': 'request_timeout'} |
There was a problem hiding this comment.
httpx.Response.json() raises ValueError/json.JSONDecodeError on invalid JSON (see similar handling in openlibrary/core/ia.py). Catching simplejson.errors.JSONDecodeError here likely won’t catch decode failures from httpx, changing behavior from returning {'error': 'request_timeout'} to raising. Consider catching json.JSONDecodeError (and/or ValueError) alongside httpx.HTTPError (or switch to requests/simplejson decoding consistently).
| except (httpx.HTTPError, JSONDecodeError) as e: | ||
| logger.exception("lending.get_availability", extra={'ids': ids}) | ||
| availabilities.update( |
There was a problem hiding this comment.
resp.json() here is from httpx (via ia.session), which typically raises ValueError/json.JSONDecodeError on invalid JSON rather than simplejson.errors.JSONDecodeError. This means JSON decode failures may now escape this handler and bubble up. Consider catching json.JSONDecodeError (and/or ValueError) alongside httpx.HTTPError.
| except (httpx.HTTPError, JSONDecodeError): | ||
| logger.exception(f"is_loaned_out_on_ia({identifier})") | ||
| return None |
There was a problem hiding this comment.
ia.session is an httpx.Client, so .json() decode failures will usually raise ValueError/json.JSONDecodeError rather than simplejson.errors.JSONDecodeError. With the narrowed except, invalid JSON may now raise instead of returning None. Consider catching json.JSONDecodeError (and/or ValueError) here too.
| except (httpx.HTTPError, JSONDecodeError): | ||
| logger.exception(f"get_loan({identifier}) 1 of 2") | ||
|
|
There was a problem hiding this comment.
Both calls to _get_ia_loan ultimately rely on httpx responses; decode failures from .json() typically raise ValueError/json.JSONDecodeError, not simplejson.errors.JSONDecodeError. These handlers may stop catching malformed JSON and allow exceptions to bubble up. Consider catching json.JSONDecodeError (and/or ValueError) in these except clauses as well.
|
It would have been nice if discussed before PR opened; the blanket exceptions weren't great but the question becomes whether these exceptions will catch all the errors we care about (did we trade a working catch-all for something too specific) |
|
Thank you @mekarpeles for the feedback! Regarding the question of whether these cover all the error types we really care about: For the For the For the database I have one question though: if we want to do an exhaustive test to cover all the possible cases, does that mean writing a test for every single exception and error type from libs we use? Will that be overkill? I am totally determined to make this absolutely right. If you think |
|
Closing as this does not follow our contributing guidelines (https://docs.openlibrary.org/developers/CONTRIBUTING.html) In this case, you're opening a PR before you're assigned to an issue. It's important that you're assigned to ensure it's an issue that staff are prioritizing to review and work on. If no issue exists you can create it. Thanks for understanding and we welcome you to find another issue follow the process linked above. |
Closes #12217
Refactor
Technical
This PR narrows the exception scope in
openlibrary/core/lending.pyby replacing broadexcept Exceptionblocks with more specific exception types, as indicated by existing TODO comments.Replaced with:
httpx.HTTPErrorfor httpx network operationsrequests.RequestExceptionfor requests-based callsJSONDecodeErrorfor JSON parsingRemoved corresponding TODO comments where addressed
Preserved expected behavior for network/API failures
Kept the broad exception in
sync_loan()intentionally, as it handles infogami-related errors without a specific exception typeTesting
TypeError,KeyError) are no longer silently swallowedScreenshot
Not applicable (no UI changes)
Stakeholders