4.1 KiB
error-codes
(no submodules)
Purpose
The @suaveplan/font-decompress package centralises every failure mode it
can produce behind a single registry built with
defineCodes("FONT_DECOMPRESS", [...]) from @suaveplan/error. The
registry is the stable contract callers depend on: code strings are
documented, frozen at module load, and never renamed without an
explicit migration. This module exports the FONT_DECOMPRESS_CODES
registry, the derived FontDecompressErrorCode literal-union type,
and the FontDecompressError class that every public failure path
raises.
FontDecompressError extends SuaveplanError<FontDecompressErrorCode>
so instanceof FontDecompressError narrows code to the union of
FONT_DECOMPRESS.* strings. The class threads cause straight
through SuaveplanError, so primitive-layer exceptions
(RangeError from DataView, TypeError from TextDecoder,
@suaveplan/font-convert errors) remain inspectable through
error.cause.
Features
- Frozen
FONT_DECOMPRESS_CODESregistry with two namespaced codes FontDecompressErrorCodeliteral-union type derived from the registryFontDecompressErrorclass extendingSuaveplanError<FontDecompressErrorCode>- Full
cause-chain preservation viaSuaveplanError - Distinct from
FONT_COMPRESS.*codes — different namespace, different class
Usage: Basic
import {
FONT_DECOMPRESS_CODES,
FontDecompressError,
} from "@suaveplan/font-decompress";
if (data.byteLength < 1) {
throw new FontDecompressError(
FONT_DECOMPRESS_CODES.INVALID_DATA,
"BTF buffer is empty",
);
}
Usage: Advanced
import {
FONT_DECOMPRESS_CODES,
FontDecompressError,
} from "@suaveplan/font-decompress";
try {
const font = unpacker.unpack(buffer);
} catch (err) {
if (err instanceof FontDecompressError) {
if (err.code === FONT_DECOMPRESS_CODES.UNPACK_FAILED) {
telemetry.increment("font.unpack.failure", {
root: err.cause instanceof Error ? err.cause.name : "unknown",
});
}
}
throw err;
}
API Reference
FONT_DECOMPRESS_CODES
A frozen object literal of two namespaced codes:
| Property | Value |
|---|---|
UNPACK_FAILED |
"FONT_DECOMPRESS.UNPACK_FAILED" |
INVALID_DATA |
"FONT_DECOMPRESS.INVALID_DATA" |
type FontDecompressErrorCode
The literal union of every value in FONT_DECOMPRESS_CODES.
class FontDecompressError extends SuaveplanError<FontDecompressErrorCode>
| Member | Type |
|---|---|
code |
FontDecompressErrorCode (narrowed) |
cause? |
unknown (inherited) |
timestamp |
number (inherited; Date.now() at construction) |
constructor(...) |
(code, message, options?: SuaveplanErrorOptions) |
Implementation Notes
defineCodes returns a Object.freezed record with null prototype,
so the registry cannot be mutated, reassigned, or extended at runtime.
The literal-type machinery preserves the exact ${Namespace}.${Reason}
string template across every consumer, so switch (err.code) enjoys
exhaustive narrowing without runtime cost.
The class's constructor passes message through to SuaveplanError's
messageKey parameter. The base class resolves the key via the i18n
resolver if one has been registered with setMessageResolver, falling
back to the raw string otherwise — so this package works without i18n
wiring and lights up automatically when @suaveplan/i18n is present.
The split from @suaveplan/font-compress preserves namespace
distinctness: an INVALID_DATA raised by the packer is
FONT_COMPRESS.INVALID_DATA; an INVALID_DATA raised by the unpacker
is FONT_DECOMPRESS.INVALID_DATA. Consumers dispatching on either
class plus its code get fully unambiguous error handling.