Skip to content

Failure model

Handle failures where the operation completes. Receiving an HTTP response, decoding JSON, and consuming an event stream are separate operations; a successful earlier stage does not guarantee the next one.

FailureWhere it appearsApplication decision
Network rejectionRequest interceptor pipeline, normally wrapped in ExchangeErrorInspect the underlying cause and decide whether replay is safe
Non-2xx HTTP statusDefault status validation throws HttpStatusValidationError, normally wrapped by the exchange managerHandle the service's error response and status; HTTP 2xx still needs business-result checks
JSON or custom extractionAfter the exchange pipeline; rejects directly to request() callerCatch around result consumption and validate the fields you use
Error interceptor itself throwsDirectly out of error handlingDo not assume every rejection is ExchangeError
SSE read/transform failureDuring asynchronous stream iterationHandle partial output and dispose the reader

Default status validation: packages/fetcher/src/validateStatusInterceptor.ts:170. Wrapping and recovery: packages/fetcher/src/interceptorManager.ts:191. Extraction: packages/fetcher/src/fetcher.ts:234 and packages/fetcher/src/resultExtractor.ts:69. An outer instanceof HttpStatusValidationError or FetchTimeoutError check alone misses a wrapped cause; inspect the ExchangeError context/cause as shown in the failure guide and error reference.

Timeout and cancellation are different controls

Request optionsTransport behaviorDeadline owner
signal suppliedNative Fetch receives it directly; library timeout is bypassedCaller combines cancellation and any desired timeout
No signal, abortController supplied, timeout enabledLibrary uses the supplied controller plus its timerLibrary clears timer after Fetch settles; caller owns controller
No signal or controller, timeout enabledLibrary creates controller and timerLibrary cleans timer and its temporary request fields
No signal, timeout disabledNative Fetch, using supplied controller if presentCaller

This precedence is implemented in packages/fetcher/src/timeout.ts:125. The timer ends when the Fetch race settles, not when subsequent response.json() or the whole SSE stream finishes. Supplying signal and timeout does not combine their deadlines. For a whole-operation deadline, own the signal and the full consumption lifecycle. Follow cancellation guidance.

Cancellation does not roll back a write already received by the server. Before retrying after a timeout or lost response, use the endpoint's idempotency and result-reconciliation contract.

Hooks change how errors reach components

useExecutePromise normally stores errors in state. propagateError rethrows general errors when enabled; an error recognized as AbortError returns to idle. execute() returns Promise<void>; read business data from result. New executions and unmount abort controllers, but a generic Promise must cooperate with that controller. See packages/react/src/core/useExecutePromise.ts:265 and React request guide.

Streams and authentication have specific recovery contracts

SSE JSON transformation calls JSON.parse; unhandled transformer errors become stream errors. Read failures surface during iteration. Early return or break cancels the reader and releases its lock; normal completion also releases the lock. The initial exchange succeeding says nothing about the remaining stream. There is no automatic reconnect, deduplication, or exactly-once delivery guarantee. See packages/eventstream/src/jsonServerSentEventTransformStream.ts:65, packages/eventstream/src/safeTransformer.ts:58, packages/eventstream/src/readableStreamAsyncIterable.ts:105, and SSE consumption reference.

The core default pipeline does not provide a general retry policy. CoSec's bounded 401 refresh path checks its own authorization header and token session, refreshes, then replays the original exchange. That is an authentication protocol, not arbitrary-error retry. Request-body replayability, write idempotency, and server outcomes remain application concerns. See packages/cosec/src/authorizationResponseInterceptor.ts:80, CoSec guide, and token refresh reference.

Released under the Apache License 2.0.