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

3.4 KiB

error-codes.ts — AUDIO_IR_LOADER.* registry

(no submodules)

Purpose

This module is the single source of truth for every error code raised by @suaveplan/audio-ir-loader. It uses defineCodes from @suaveplan/error to register an immutable, byte-stable mapping of short keys (MANIFEST_MISMATCH) to fully-qualified strings (AUDIO_IR_LOADER.MANIFEST_MISMATCH). It also declares the AudioIrLoaderError class, which exposes every dimension an operator might filter on (id, extension, field, manifestValue, decodedValue, maxBytes, decodedBytes, errors) as typed read-only properties so dashboards and routing layers never have to parse message text to know what happened.

Features

  • Six codes — DECODER_UNAVAILABLE, MANIFEST_MISMATCH, ABORTED, CACHE_OVERFLOW, DECODE_FAILED, RESOLVE_FAILED.
  • Frozen registry object — Object.isFrozen(AUDIO_IR_LOADER_CODES) is true.
  • Typed error class with discriminants pre-typed on the class.
  • Aggregate errors[] for the DECODE_FAILED partial-failure path from preload.

Usage: Basic

import {
    AUDIO_IR_LOADER_CODES,
    AudioIrLoaderError,
} from "@suaveplan/audio-ir-loader";

throw new AudioIrLoaderError(
    AUDIO_IR_LOADER_CODES.DECODER_UNAVAILABLE,
    "no decoder registered for .flac",
    { id: "club-club1", extension: "flac" }
);

Usage: Advanced

The aggregate errors discriminant powers the preload partial-failure contract:

import { AudioIrLoaderError, AUDIO_IR_LOADER_CODES } from "@suaveplan/audio-ir-loader";

try {
    await loader.preload(["a", "b", "c"]);
} catch (err) {
    if (
        err instanceof AudioIrLoaderError &&
        err.code === AUDIO_IR_LOADER_CODES.DECODE_FAILED
    ) {
        for (const { id, error } of err.errors ?? []) {
            console.error(`load ${id} failed:`, error.code);
        }
    }
}

Operators routing on the structured discriminants can ship dashboards that break down failures by extension for DECODER_UNAVAILABLE, by field for MANIFEST_MISMATCH, and by the size pair (maxBytes / decodedBytes) for CACHE_OVERFLOW, with zero message-text regexes.

API Reference

AUDIO_IR_LOADER_CODES

Frozen Readonly<Record<Key, "AUDIO_IR_LOADER.<Key>">> with keys DECODER_UNAVAILABLE, MANIFEST_MISMATCH, ABORTED, CACHE_OVERFLOW, DECODE_FAILED, RESOLVE_FAILED.

AudioIrLoaderError extends SuaveplanError

Constructor: (code, message, options?). Discriminants on the instance: id, extension, field, manifestValue, decodedValue, maxBytes, decodedBytes, errors. name === "AudioIrLoaderError".

AudioIrLoaderErrorOptions

Extends SuaveplanErrorOptions with the seven optional discriminants listed on the class plus errors: readonly AggregatedLoadFailure[].

AggregatedLoadFailure

{ id: string; error: SuaveplanError } — one entry per failed id in a preload aggregate.

Implementation Notes

defineCodes returns a frozen object; the registry guarantees byte-stable code strings across builds. The discriminants on AudioIrLoaderError are declared as T | undefined rather than via exactOptionalPropertyTypes gymnastics so callers reading the property always get an unambiguous "absent" sentinel. Every code in this registry is exercised by a real call site under test (see error-codes.test.ts) — the exhaustion test guarantees we cannot register a code that has no production thrower.