first commit
This commit is contained in:
101
docs/foundation/flow/streams/src/errors/stream-error.md
Normal file
101
docs/foundation/flow/streams/src/errors/stream-error.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# stream-error
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Defines the structured error hierarchy for the `@suaveplan/streams` package. Every runtime error emitted by stream operations is an instance of `StreamError` (which extends `SuaveplanError`) and carries a stable, dot-namespaced error code from the `STREAM.*` registry. This design means callers can narrow errors programmatically — `error.code === STREAM_CODES.ABORTED` — without string-matching unstructured messages, and ensures that OTel integrations, log pipelines, and dead-letter queues can route stream errors reliably.
|
||||
|
||||
The codes are registered once via `defineCodes("STREAM", [...])` and reused across every throw site. Codes are intentionally coarse-grained: they represent the semantic category of failure, not the specific call stack location, so they remain stable across refactors.
|
||||
|
||||
## Features
|
||||
|
||||
- Six concrete error subclasses covering all stream failure modes
|
||||
- Stable `STREAM.*` error code registry via `defineCodes`
|
||||
- Exported `StreamErrorCode` union type for exhaustive switch statements
|
||||
- Each subclass propagates `cause` when it is an `Error` instance
|
||||
- All classes extend `StreamError` which extends `SuaveplanError`, compatible with the project error wire format
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { StreamAbortedError, STREAM_CODES } from "@suaveplan/streams/errors/stream-error";
|
||||
|
||||
function checkAborted(signal?: AbortSignal): void {
|
||||
if (signal?.aborted) {
|
||||
throw new StreamAbortedError({ cause: signal.reason });
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
checkAborted(AbortSignal.abort());
|
||||
} catch (err) {
|
||||
if (err instanceof StreamAbortedError) {
|
||||
console.log(err.code); // "STREAM.ABORTED"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
StreamTransformFailedError,
|
||||
StreamClosedError,
|
||||
StreamReadFailedError,
|
||||
STREAM_CODES,
|
||||
} from "@suaveplan/streams/errors/stream-error";
|
||||
|
||||
function handleStreamError(err: unknown): never {
|
||||
if (!(err instanceof Error)) {
|
||||
throw new StreamReadFailedError({ message: "Unknown read failure" });
|
||||
}
|
||||
switch ((err as { code?: string }).code) {
|
||||
case STREAM_CODES.CLOSED:
|
||||
throw new StreamClosedError({ message: "Cannot read from closed stream" });
|
||||
case STREAM_CODES.TRANSFORM_FAILED:
|
||||
throw new StreamTransformFailedError({ cause: err });
|
||||
default:
|
||||
throw new StreamReadFailedError({ cause: err });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `STREAM_CODES`
|
||||
|
||||
`Record<string, string>` — the stable code map. Keys: `ABORTED`, `BACKPRESSURE_EXCEEDED`, `CHUNK_INVALID`, `PIPE_FAILED`, `TRANSFORM_FAILED`, `SOURCE_EXHAUSTED`, `READ_FAILED`, `WRITE_FAILED`, `CLOSED`. Values are dot-namespaced strings like `"STREAM.ABORTED"`.
|
||||
|
||||
### `StreamError`
|
||||
|
||||
Base class. Extends `SuaveplanError<StreamErrorCode>`. All concrete subclasses inherit from this.
|
||||
|
||||
### `StreamAbortedError`
|
||||
|
||||
Thrown when an `AbortSignal` fires mid-operation. Constructor: `{ cause?: unknown; message?: string }`.
|
||||
|
||||
### `StreamTransformFailedError`
|
||||
|
||||
Thrown when a user-supplied transform function throws. Constructor: `{ cause?: unknown; message?: string }`.
|
||||
|
||||
### `StreamClosedError`
|
||||
|
||||
Thrown when an operation is attempted on a closed stream. Constructor: `{ message?: string }`.
|
||||
|
||||
### `StreamReadFailedError`
|
||||
|
||||
Thrown on unrecoverable read failures. Constructor: `{ cause?: unknown; message?: string }`.
|
||||
|
||||
### `StreamWriteFailedError`
|
||||
|
||||
Thrown on unrecoverable write failures. Constructor: `{ cause?: unknown; message?: string }`.
|
||||
|
||||
### `StreamPipeFailedError`
|
||||
|
||||
Thrown when a pipe or pipeline composition fails. Constructor: `{ cause?: unknown; message?: string }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`defineCodes` generates stable string codes by joining the namespace prefix and the key with a dot. The generated values are frozen at module-init time and never change, which means error codes survive across serialization round-trips (they appear verbatim in JSON error envelopes). Cause propagation is conditional: we only set `cause` when the original value `instanceof Error` to avoid accidentally serializing non-Error objects into the error chain.
|
||||
Reference in New Issue
Block a user