Repository navigation
fix: don't cache Response objects with error status codes - #575
Open
RitiGrover wants to merge 1 commit into
Open
RitiGrover wants to merge 1 commit into
RitiGrover wants to merge 1 commit into
Conversation
@cache only checks whether the result is a Response to encode it, it never looks at the status code. An endpoint that returns an error Response directly (rather than raising HTTPException) gets that response cached as-is; a later cache hit replays the cached body but the wrapper always returns a plain 200, so the client sees a 200 with error content instead of the original status. Skip caching entirely for a Response with status_code >= 400 and return it directly, matching how uncacheable requests are already handled. Fixes long2ice#554
This branch has not been deployed
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.
Description
@cacheonly checks whether the wrapped function's result is aResponseto know how to encode it - it never looks at the status code. If an endpoint returns an errorResponsedirectly (a common alternative to raisingHTTPException, e.g. via custom response shortcuts), that response gets cached exactly like a success response. On the next cache hit, the wrapper returns the cached body but the response object it hands back defaults to 200, so the client sees a 200 with the error's JSON body instead of the original error status.Motivation and Context
Fixes #554. Nothing in the cache entry records the original status code, so there's no way to "correctly" cache an error response without a bigger change to what gets stored. The minimal, safe fix is to just not cache it - matching how requests that are already
_uncacheable()are handled (skip caching, return the result as-is).How Has This Been Tested?
cache_error_response_objtoexamples/in_memory/main.py, returning aJSONResponsewithstatus_code=404and an incrementing counter in the body.test_cache_error_response_obj_is_not_cached, asserting the status code stays 404 and the counter increments across two calls (proving it isn't cached).200with the cached (stale) body; with the fix, both calls correctly return404with fresh bodies.tests/test_decorator.pysuite: my new test passes, and the two pre-existing failures (test_datetime- timing-sensitive,test_non_get- unrelatedPUTon aGET-only route) are present identically onmainbefore my change, so nothing here is a regression.ruff checkclean on all changed files (the formatting suggestionsruff formatmakes ondecorator.py/main.py/test_decorator.pyare all pre-existing, on lines I didn't touch, so I left them alone rather than reformatting unrelated code).