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.