Skip to content
IC Reactor

isRetryableReactorError

isRetryableReactorError(error): boolean

Defined in: core/src/errors/index.ts:520

Whether retrying a failed canister call could plausibly produce a different result.

The rule is “retry only what the agent reports as a condition that could differ next time”. Concretely:

  • CanisterError — the canister returned an Err variant. Never.
  • ValidationError — refused by a validator client-side. Never.
  • CallError — Reactor.callMethod wraps everything else in one of these, including our own Candid encode/decode and transform failures, so the wrapper alone says nothing. The decision comes from the cause:
    • an agent error (it carries a kind): retried, except for a rejection whose reject code is one the replica will simply repeat, and an HTTP 4xx answer other than 408 and 429;
    • anything else: not retried, because no agent error means no request was ever made — the failure happened in encoding, decoding or transforming, and the identical input produces the identical failure.
  • any other error: not retried, for the same reason.

An HTTP 4xx answer is a refusal of the request itself: an expired or invalid delegation, a bad signature, a malformed request. The agent has already sent it retryTimes more times (3 by default) before it reports the error, so a query retry would only repeat those attempts, about 20 seconds of them for a session whose delegation has lapsed. 408 and 429 still retry, as do 5xx answers.

Within agent errors the bias is toward retrying: an unrecognised kind, or a rejection whose code cannot be read, still retries, so an unfamiliar transport-level fault is never silently made fatal.

unknown

boolean

Opt in on a QueryClient you construct yourself

new QueryClient({
defaultOptions: { queries: { retry: reactorRetry } },
})