Results, Errors, and Cancellation
Use results, errors, and cancellation with the current published Askr packages.
@askrjs/askr0.0.59
How to use results, errors, and cancellation
Pass AbortSignal through the client call, distinguish typed problem responses from transport failures, and do not retry cancellations.
- Import the published @askrjs/askr entrypoint.
- Keep results, errors, and cancellation configuration next to the component, route, or server composition root that owns it.
- Handle pending, unavailable, cancellation, and failure states, then verify the production path.
const controller = new AbortController();
const result = await api.projects.get({ params: { id }, signal: controller.signal });
if (!result.ok) return <ProjectError problem={result.error} />;
return <ProjectDetails project={result.data} />;Result handling
Every client and createFetch() call returns a FetchResult instead of throwing. Check result.ok first, or switch on result.kind — "success", "http", "request", "network", "timeout", "abort", "decode", or "middleware" — to route to the right handling. unwrap(result) is there for call sites that prefer exceptions; it throws a FetchError carrying the original result on its .result property.
Problem responses
Any status code you registered with .errors() on an endpoint decodes into a typed HttpResult: ok is false, kind is "http", status matches the response, and error is the value your error codec parsed out of the body. That means a 404 or 422 response is available as typed data on the result, not as something you have to catch or re-parse from a generic error object.
Abort signals
Pass a signal on an individual call to compose your own AbortController with the client's cancellation handling — the request is aborted if either signal fires. Cancellation initiated by the caller resolves with kind: "abort", while a request that exceeds its timeout resolves with kind: "timeout", so the two are distinguishable without inspecting the abort reason yourself.
Retries
Set timeout on the client or on an individual call to bound how long a request waits before failing with kind: "timeout". Actual retry behavior comes from @askrjs/fetch/middleware's retry() middleware, which by default retries GET, HEAD, PUT, DELETE, and OPTIONS on 408, 425, 429, 500, 502, 503, and 504, honoring a Retry-After header when the server sends one. Requests carrying a body are skipped by default since the middleware has no way to know they're safe to resend.