fix(api): mark schema-validation errors as non-retryable
The proxy returned `{fonts: null, total: 0}` for empty results, which
fetchProxyFonts surfaced as a generic Error. fontCatalogStore wrapped it
as FontNetworkError, and TanStack retried 3× with exponential backoff —
pinning the loading skeleton for ~7s before settling on an empty list.
Schema mismatches are deterministic; retrying only delays surfacing the
contract violation.
- shared/api/queryClient: introduce NonRetryableError marker class.
The default retry handler short-circuits when it sees this so any
store using the shared client gets fail-fast behavior for free.
- entities/Font/lib/errors: FontResponseError extends NonRetryableError.
- entities/Font/api/proxy/proxyFonts: throw FontResponseError (was a
bare Error). Document that ProxyFontsResponse.fonts is always an array.
- entities/Font/.../fontCatalogStore.fetchPage: preserve a
FontResponseError raised lower in the stack instead of re-wrapping
it as FontNetworkError.
- features/FilterAndSortFonts/api/filters: throw NonRetryableError on
invalid filters payloads and document the array-never-null contract.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { NonRetryableError } from '$shared/api/queryClient';
|
||||
|
||||
/**
|
||||
* Thrown when the network request to the proxy API fails.
|
||||
* Wraps the underlying fetch error (timeout, DNS failure, connection refused, etc.).
|
||||
@@ -12,11 +14,13 @@ export class FontNetworkError extends Error {
|
||||
|
||||
/**
|
||||
* Thrown when the proxy API returns a response with an unexpected shape.
|
||||
* Extends NonRetryableError because schema mismatches are not transient —
|
||||
* retrying will produce the same failure and only delay surfacing the bug.
|
||||
*
|
||||
* @property field - The name of the field that failed validation (e.g. `'response'`, `'response.fonts'`).
|
||||
* @property received - The actual value received at that field, for debugging.
|
||||
*/
|
||||
export class FontResponseError extends Error {
|
||||
export class FontResponseError extends NonRetryableError {
|
||||
readonly name = 'FontResponseError';
|
||||
|
||||
constructor(
|
||||
|
||||
Reference in New Issue
Block a user