Files
2026-05-27 23:47:53 +01:00

3.5 KiB

bytes-error

(no submodules)

Purpose

bytes-error.ts defines the typed error substrate for @suaveplan/bytes. It registers all stable error codes under the "BYTES" namespace using defineCodes from @suaveplan/error, exposes the BytesCode union type that constrains which codes BytesError instances can carry, and re-exports the concrete BytesError class whose constructor widens visibility from protected to public.

By funnelling all package errors through a single typed class with a stable code registry, callers can narrow on err instanceof BytesError and then switch on err.code without any string fragility.

Features

  • BYTES_CODES — immutable record mapping human-readable dotted keys (e.g. "ENCODE.INVALID_HEX") to stable prefixed string codes ("BYTES.ENCODE.INVALID_HEX"), produced by defineCodes.
  • BytesCode — TypeScript union type of all values in BYTES_CODES; used as the generic parameter of BytesError.
  • BytesError — extends SuaveplanError<BytesCode>; carries a stable code, a human-readable message, and an optional cause chain via SuaveplanErrorOptions.
  • Stable code registry — codes are registered once and never change; adding a new code is a non-breaking addition; removing one is a breaking change.

Usage: Basic Example

import { BytesError, BYTES_CODES } from "@suaveplan/bytes/errors";

throw new BytesError(
    BYTES_CODES["ENCODE.INVALID_HEX"],
    "Hex string has odd length: 3 characters"
);

Usage: Advanced Example

import { BytesError, BYTES_CODES } from "@suaveplan/bytes/errors";

function assertHex(value: string): void {
    if (value.length % 2 !== 0) {
        throw new BytesError(
            BYTES_CODES["ENCODE.INVALID_HEX"],
            `Invalid hex string: odd length (${value.length})`,
            { cause: new RangeError("Length must be even") }
        );
    }
}

// Callers can narrow:
try {
    assertHex("abc");
} catch (err) {
    if (err instanceof BytesError) {
        console.error(err.code); // "BYTES.ENCODE.INVALID_HEX"
    }
}

API Reference

BYTES_CODES

Record<string, BytesCode> — maps dotted keys to prefixed code strings:

Key Code
"ENCODE.INVALID_HEX" "BYTES.ENCODE.INVALID_HEX"
"ENCODE.INVALID_BASE64" "BYTES.ENCODE.INVALID_BASE64"
"ENCODE.INVALID_UTF8" "BYTES.ENCODE.INVALID_UTF8"
"UINT8.INVALID_INPUT" "BYTES.UINT8.INVALID_INPUT"
"UINT8.FORMAT_MISMATCH" "BYTES.UINT8.FORMAT_MISMATCH"
"UUID.INVALID_LENGTH" "BYTES.UUID.INVALID_LENGTH"
"UUID.INVALID_FORMAT" "BYTES.UUID.INVALID_FORMAT"

BytesCode

type BytesCode = (typeof BYTES_CODES)[keyof typeof BYTES_CODES]

Union type of all code strings. Used as the generic argument to SuaveplanError.

BytesError

class BytesError extends SuaveplanError<BytesCode> {
    public constructor(code: BytesCode, message: string, options?: SuaveplanErrorOptions);
}

Typed error for all @suaveplan/bytes failures. The constructor widens visibility from the protected base to public.

Implementation Notes

defineCodes from @suaveplan/error produces a frozen object whose values are the exact strings that will be serialised over the wire. The "BYTES." prefix guarantees no collision with codes from other packages. The as const assertion on the code-name array preserves tuple literal types so TypeScript can verify exhaustiveness in switch (err.code) statements.