12 KiB
@suaveplan/error - Foundation error substrate — SuaveplanError base class, stable code registry, cause-chain traversal, Zod-validated wire format (JSON + MessagePack), redaction, OTel span-event adapter, i18n resolver hook. Zero @suaveplan/* deps.
Summary
Foundation error substrate for Suaveplan. Every non-testing @suaveplan/* package extends this library's SuaveplanError base class and uses its stable code registry. The package provides: SuaveplanError<TCode> — an abstract base with literal-typed discriminant codes, injectable clock, context bag, traceId, and cause chaining; defineCodes(namespace, reasons) — a frozen, literal-typed registry that makes error codes refactor-safe; walkCauses(err) — a cycle-safe, depth-bounded generator for traversing nested error causes; lossless JSON and binary wire formats (toJSON/fromJSON/toBinary/fromBinary) with Zod validation; markSensitive/unwrapSensitive for redaction at serialization boundaries; toSpanEvent for OpenTelemetry exception span events without an OTel SDK import; and a setMessageResolver hook for i18n. Zero @suaveplan/* runtime or peer dependencies — this is the lowest-level package in the stack.
Documentation tree
- package-error —
ErrorPackageErroris the one concreteSuaveplanErrorsubclass shipped by@suaveplan/erroritself. It carries the… - suaveplan-error —
SuaveplanErroris the abstract base class that every non-testing package in the project extends. It standardises the… - causes — (no submodules)
- walk-causes — (no submodules)
- define-codes —
defineCodesis the canonical way to declare a stable, literal-typed error code registry for a package. It takes a nam… - error-codes —
ERROR_CODESis the package-local registry for@suaveplan/erroritself. It enumerates every failure mode the foundat… - i18n — (no submodules)
- resolver — (no submodules)
- otel — (no submodules)
- to-span-event — (no submodules)
- redact — (no submodules)
- sensitive — (no submodules)
- from-binary —
fromBinaryis the decode counterpart totoBinary. It accepts aUint8Arrayproduced bytoBinary(or any compatib… - from-json —
fromJSONis the decode counterpart totoJSON. It Zod-validates the incoming payload againstwireErrorSchemaand r… - to-binary —
toBinaryencodes any error-shaped value into a compact byte payload suitable for binary transports (message queues, W… - to-json —
toJSONserialises any error-shaped value to a wire-safe plain object that round-trips losslessly back through `fromJS…
- error-codes —
ERROR_CODESis the package-local registry for@suaveplan/erroritself. It enumerates every failure mode the foundat… - i18n — (no submodules)- resolver — (no submodules)- otel — (no submodules)- to-span-event — (no submodules)- redact — (no submodules)- sensitive — (no submodules)- from-binary —
fromBinaryis the decode counterpart totoBinary. It accepts aUint8Arrayproduced bytoBinary(or any compatib… - from-json —
fromJSONis the decode counterpart totoJSON. It Zod-validates the incoming payload againstwireErrorSchemaand r… - to-binary —
toBinaryencodes any error-shaped value into a compact byte payload suitable for binary transports (message queues, W… - to-json —
toJSONserialises any error-shaped value to a wire-safe plain object that round-trips losslessly back through `fromJS… - walk-causes — (no submodules)- define-codes —
defineCodesis the canonical way to declare a stable, literal-typed error code registry for a package. It takes a nam… - error-codes —
ERROR_CODESis the package-local registry for@suaveplan/erroritself. It enumerates every failure mode the foundat… - i18n — (no submodules)- resolver — (no submodules)- otel — (no submodules)- to-span-event — (no submodules)- redact — (no submodules)- sensitive — (no submodules)- from-binary —
fromBinaryis the decode counterpart totoBinary. It accepts aUint8Arrayproduced bytoBinary(or any compatib… - from-json —
fromJSONis the decode counterpart totoJSON. It Zod-validates the incoming payload againstwireErrorSchemaand r… - to-binary —
toBinaryencodes any error-shaped value into a compact byte payload suitable for binary transports (message queues, W… - to-json —
toJSONserialises any error-shaped value to a wire-safe plain object that round-trips losslessly back through `fromJS… - walk-causes — (no submodules)- define-codes —
defineCodesis the canonical way to declare a stable, literal-typed error code registry for a package. It takes a nam… - error-codes —
ERROR_CODESis the package-local registry for@suaveplan/erroritself. It enumerates every failure mode the foundat… - i18n — (no submodules)- resolver — (no submodules)- otel — (no submodules)- to-span-event — (no submodules)- redact — (no submodules)- sensitive — (no submodules)- from-binary —
fromBinaryis the decode counterpart totoBinary. It accepts aUint8Arrayproduced bytoBinary(or any compatib… - from-json —
fromJSONis the decode counterpart totoJSON. It Zod-validates the incoming payload againstwireErrorSchemaand r… - to-binary —
toBinaryencodes any error-shaped value into a compact byte payload suitable for binary transports (message queues, W… - to-json —
toJSONserialises any error-shaped value to a wire-safe plain object that round-trips losslessly back through `fromJS… - walk-causes — (no submodules)- define-codes —
defineCodesis the canonical way to declare a stable, literal-typed error code registry for a package. It takes a nam… - error-codes —
ERROR_CODESis the package-local registry for@suaveplan/erroritself. It enumerates every failure mode the foundat… - i18n — (no submodules) - resolver — (no submodules)- otel — (no submodules) - to-span-event — (no submodules)- redact — (no submodules) - sensitive — (no submodules)- from-binary —
fromBinaryis the decode counterpart totoBinary. It accepts aUint8Arrayproduced bytoBinary(or any compatib… - from-json —
fromJSONis the decode counterpart totoJSON. It Zod-validates the incoming payload againstwireErrorSchemaand r… - to-binary —
toBinaryencodes any error-shaped value into a compact byte payload suitable for binary transports (message queues, W… - to-json —
toJSONserialises any error-shaped value to a wire-safe plain object that round-trips losslessly back through `fromJS…
Install
bun add @suaveplan/error
Highlights
SuaveplanError<TCode>— abstract base with literal-typed code discriminants, injectable clock, context, traceId, causedefineCodes(namespace, reasons)— frozen, literal-typed code registrywalkCauses(err)— cycle-safe, depth-bounded cause-chain generatortoJSON/fromJSON/toBinary/fromBinary— lossless, Zod-validated wire format; binary form is UTF-8-encoded canonical JSON, no external encodermarkSensitive/unwrapSensitive— redaction tagging applied at the serialization boundarytoSpanEvent— OpenTelemetryexceptionspan event payload, no OTel SDK importsetMessageResolver— i18n hook; default resolver returns the key verbatim
Foundation rules honoured
- Zero
@suaveplan/*runtime or peer deps - Runtime deps:
tslib,zod - Zero Node / browser built-in references in
src/(guarded bytests/no-disallowed.test.ts) sideEffects: false, per-module subpath exports- 100% statement / branch / function / line coverage (guarded in
vitest.config.ts)
Usage
import { defineCodes, SuaveplanError } from "@suaveplan/error";
export const AUTH_CODES = defineCodes("AUTH", [
"LOGIN.INVALID",
"LOGIN.LOCKED",
] as const);
export class AuthError extends SuaveplanError<
(typeof AUTH_CODES)[keyof typeof AUTH_CODES]
> {
public constructor(
code: (typeof AUTH_CODES)[keyof typeof AUTH_CODES],
key: string,
options?: ConstructorParameters<typeof SuaveplanError>[2]
) {
super(code, key, options);
}
}
throw new AuthError(AUTH_CODES["LOGIN.INVALID"], "error.auth.login.invalid", {
context: { user: "alice" },
traceId: "trace-1",
});
Wire format
toJSON(err) returns a plain object with __suaveplanError: 1, ready for JSON-safe transport. fromJSON(value) validates and reconstructs the payload. toBinary / fromBinary exchange the same content as a UTF-8 byte array.
Testing
bunx turbo lint typecheck test --filter=@suaveplan/error
bunx turbo test:coverage --filter=@suaveplan/error