-
Notifications
You must be signed in to change notification settings - Fork 473
Open
Description
Describe the bug
In urql's React Suspense mode, error results are cached in the internal React-specific cache (client._react) and persist even when:
- Error boundaries are reset
- The component is re-rendered
This behavior prevents proper error recovery in Suspense mode because cached errors are thrown repeatedly without attempting to refetch data.
Steps to reproduce:
- Start the app (invalid URL is set by default)
- Verify that the error is caught by the Error Boundary
- Click the "Try again" button to reset the Error Boundary
- Expected: A new request to
/graphqlappears in the Network tab - Actual: No request is made - the cached error is thrown immediately
Root Cause Analysis
The issue is in packages/react-urql/src/hooks/useQuery.ts:
- Line 240-241: All
OperationResults (including errors) are cached without filtering:
onPush(result => {
cache.set(request.key, result); // Caches both success and error results
});- Line 262-292: The cache is checked without considering error state:
let result = cache.get(request.key);
// Cached error results are returned without refetching- cache.ts: The cache implementation treats errors as valid cache entries:
type CacheEntry = OperationResult | Promise<unknown> | undefined;
// OperationResult includes both success and error statesExpected Behavior
To allow for proper error recovery and retry mechanisms, I think it might be better if error results weren't cached in the Suspense cache. What do you think?
Proposed Solutions
Don't cache error results
onPush(result => {
if (!result.error) {
cache.set(request.key, result);
}
});Reproduction
https://github.com/hushin-sandbox/urql-react-suspense-error-cache-repro https://stackblitz.com/~/github.com/hushin-sandbox/urql-react-suspense-error-cache-repro
Urql version
- urql: v5.0.1
- @urql/core: v6.0.1
Validations
- I can confirm that this is a bug report, and not a feature request, RFC, question, or discussion, for which GitHub Discussions should be used
- Read the docs.
- Follow our Code of Conduct
Metadata
Metadata
Assignees
Labels
No labels