Askr
Server & APIs

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.

  1. Import the published @askrjs/askr entrypoint.
  2. Keep results, errors, and cancellation configuration next to the component, route, or server composition root that owns it.
  3. 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.