Skip to article

Deadlines and cancellation

Bound the complete call and each attempt, and stop the chain when callers cancel.

Every attempt shares one deadline
  1. Call startsOverall budget begins
  2. Each attemptUses the smaller remaining budget
  3. Deadline / abortStop waiting and stop the chain

An attempt budget never extends the overall deadline. Cancellation cannot undo a request already received by a provider.

On this page

Two budgets, one deadline

timeoutMs bounds the complete normalized call, including attempts and JSON parsing. attemptTimeoutMs bounds each attempt without extending the total deadline. Both default to the configured total budget; with defaults, a full-budget timeout leaves no time for fallback.

Configuration
const policy = {
  timeoutMs: 10_000,
  attemptTimeoutMs: 4_000,
};
// Pass these fields alongside provider and optional fallback to createSearch().

Cancel with AbortSignal

cancel.ts · fixture
import { createSearch, SearchError } from '@belweave/search-sdk';
import { createMockProvider } from '@belweave/search-sdk/testing';

const controller = new AbortController();
const client = createSearch({ provider: createMockProvider({ delayMs: 500 }) });
const pending = client.web.search(
  { query: 'SQLite concurrency' },
  { signal: controller.signal },
);

controller.abort();
try {
  await pending;
} catch (error) {
  if (error instanceof SearchError) console.log(error.code); // aborted
  else throw error;
}

Cancellation aborts the current attempt and prevents later providers from starting. A pre-aborted signal fails before provider dispatch. The SDK cleans up its own timers and listeners.

Understand resource limits

JavaScript timers require the event loop to yield. When provider work eventually settles, elapsed deadlines take precedence over a late success or failure.