Repository navigation
Surface metadata source failures instead of returning an empty result - #9
Open
johnnyxmas wants to merge 1 commit into
Open
johnnyxmas wants to merge 1 commit into
johnnyxmas wants to merge 1 commit into
Conversation
BookInfoProxy.Search wrapped the call to the search proxy in a blanket catch (Exception) that logged a warning and returned an empty list, so any failure to reach the metadata source rendered as "no results found". That is indistinguishable from a genuine empty result, which makes a metadata outage look like the author or book simply does not exist. GoodreadsException already derives from NzbDroneClientException with HttpStatusCode.ServiceUnavailable, i.e. it is built to be surfaced, and CandidateService already catches GoodreadsException explicitly to degrade gracefully during import identification. The blanket catch here swallowed the exception before that handler could ever observe it, leaving it effectively dead code. Rethrow GoodreadsException so callers see it, and keep the existing empty-list fallback for other unexpected errors. Import identification behaviour is unchanged because CandidateService still handles it; interactive search now reports the failure rather than silently showing nothing.
4 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BookInfoProxy.Searchwraps the search proxy call in a blanketcatch (Exception)that logs a warning and returns an empty list:So any failure to reach the metadata source renders as "no results found", which is indistinguishable from a genuine empty result. A metadata outage looks to the user like the author or book simply does not exist.
This is currently very visible, because the origin rate limits aggressively (see #8). Searching
dunereturns 25 results whileLouis Armstrong, plainArmstrongandtolkienall return 0 — not because those have no books, but because the origin answered429:Why rethrowing is the right fix
Two things indicate the exception was always meant to propagate:
GoodreadsExceptionderives fromNzbDroneClientExceptionand is constructed withHttpStatusCode.ServiceUnavailable, so it is already designed to surface as a 503 with a message rather than be swallowed.CandidateServicealready catchesGoodreadsExceptionto degrade gracefully during import identification:Because the blanket catch in
BookInfoProxyruns first, that handler can never observe the exception — it is effectively dead code today.Change
Rethrow
GoodreadsException, keeping the existing empty-list fallback for other unexpected errors.CandidateServicestill catches it and falls back to an empty candidate list, which is what it already intended to do.Considered and rejected: retrying with back-off
BookInfoProxyhas aWaitUntilRetryhelper used on other paths, but it callsThread.Sleepon theRetry-Aftervalue. The origin currently returnsretry-after: 132, so retrying a user-initiated search would block the request for over two minutes. Failing fast with an accurate message seemed clearly preferable for the interactive path; happy to revisit if you would rather have a bounded retry.Test plan
GoodreadsExceptionresolves inBookInfoProxy(using NzbDrone.Core.MetadataSource.Goodreadsalready present) and is the same typeCandidateServicecatchesNzbDroneClientExceptionwithServiceUnavailable, so it maps to a 503 rather than an unhandled 500