Skip to content

Implementation / Field notes

Trace cancellations in a streaming AI request

Follow cancellation from the user connection through model and tool work, preserving partial output and the final request state.

By DriftRail · Updated

Trace streaming cancellation as a request outcome and a propagation path. Record when cancellation was observed, which operations stopped, what output had already been delivered, and whether a consequential action had already completed.

A closed tab is not a completed task

A client may disconnect after the first chunk while the application continues generation or starts a tool. A single “stream closed” event hides whether work stopped, finished, or failed. Keep user cancellation distinct from provider failure and successful completion.

Exercise cancellation at meaningful points

  1. Cancel before generation starts and confirm no unnecessary downstream work begins.
  2. Cancel after one chunk and record partial delivery without treating it as a complete answer.
  3. Cancel while a tool is running; distinguish cancellation requested from cancellation acknowledged.
  4. Check that a final-state event is emitted once and that later callbacks do not overwrite it as success.

What AbortSignal does and does not establish

An abort signal communicates cancellation to code that observes it. It does not automatically undo an external side effect or stop a library that ignores the signal. Check the exact client’s cancellation support, timeout behavior, and billing semantics separately.

Read the local example

The fixture uses a local abort signal, emits one chunk, and refuses to produce the next synthetic chunk after abort. Its terminal outcome is canceled with one delivered chunk. It intentionally makes no network call and therefore does not establish cancellation support in a model provider or this application’s streaming endpoint.

Run the worked example

Save the synthetic Node.js example and run node trace-streaming-request-cancellations.mjs with Node.js 22 or newer. The assertions check the illustrated records and calculations; they do not test a deployed provider, SDK, or access control. No credentials or network connection are needed.

// Synthetic teaching fixture. No credentials, network calls, or production verification.
import assert from 'node:assert/strict';

const controller = new AbortController();
const delivered = [];
const emit = text => { controller.signal.throwIfAborted(); delivered.push(text); };
emit('partial answer');
controller.abort();
assert.throws(() => emit('must not be delivered'));
const terminal = { outcome: 'canceled', deliveredChunks: delivered.length };
assert.equal(terminal.deliveredChunks, 1);
assert.equal(terminal.outcome, 'canceled');
console.log(JSON.stringify(terminal));

References and further reading

Maintained by DriftRail. AI assisted the October 2026 content and template revision. Examples are illustrative; they are not measured product benchmarks. Suggest a correction.

From understanding to evidence

Observe your AI in production.

Explore event logging, detections, and review workflows in DriftRail.

Open DriftRail ↗Read the documentation →