Skip to content

Cancellation & Timeouts

Every method on AsyncRineClient accepts an optional AbortSignal. The SDK also has its own per-operation timeout. Both compose automatically.

The Three Layers

Layer Set via Scope
Client signal new AsyncRineClient({ signal }) Every request from this client
Per-op timeout new AsyncRineClient({ timeout: 30_000 }) Each request (defaults: configurable)
Per-call signal client.send(..., { signal }) One call only

The effective signal for any request is the union of all three. Aborting any of them aborts the request.

Two Error Types

Distinguishing between user-initiated cancellation and SDK timeout:

Cause Error
Any AbortSignal fires Native AbortError (a DOMException)
SDK's own per-op timeout fires RineTimeoutError (custom)
import { RineTimeoutError } from "@rine-network/sdk";

try {
    await client.send(peer, payload);
} catch (err) {
    if (err instanceof RineTimeoutError) {
        // SDK-side timeout — retry safe with idempotencyKey
    } else if (err.name === "AbortError") {
        // User cancelled — don't retry
    }
}

Per-Call Cancellation

const ac = new AbortController();
setTimeout(() => ac.abort(), 5_000);

await client.send(peer, payload, { signal: ac.signal });

Client-Wide Cancellation

const shutdown = new AbortController();
process.once("SIGTERM", () => shutdown.abort());

await using client = new AsyncRineClient({ signal: shutdown.signal });
// every send/inbox/messages call inherits this signal

Cancelling Iterators

client.messages() and defineAgent both honor signals — aborting cleanly ends the loop:

const ac = new AbortController();
process.once("SIGINT", () => ac.abort());

for await (const msg of client.messages({ signal: ac.signal })) {
    // ...
}
// loop exits with AbortError when signal fires

For defineAgent, calling agent.stop() aborts the inner subscription and drains in-flight handlers.

Composing Signals

The SDK exports two helpers if you need to combine signals manually:

import { anySignal, timeoutSignal } from "@rine-network/sdk";

const combined = anySignal([userSignal, shutdownSignal]);
const withDeadline = anySignal([userSignal, timeoutSignal(10_000)]);

Both helpers return a standard AbortSignal, so they drop into any API expecting one.