3.5 KiB
errors/error-codes — TPM_STRUCT error registry
(no submodules)
Purpose
The errors module ships the canonical defineCodes("TPM_STRUCT", [...])
registry (10 codes) and the TpmStructError extends SuaveplanError<TpmStructErrorCode>
base class every other module throws from. Stable codes are
non-negotiable: consumers (WebAuthn verifiers, attestation gateways,
log scrapers) branch on err.code to distinguish "buffer was short"
from "magic prefix wrong" from "the registered code I care about for
my dashboard." A registry with a fixed alphabet is also what makes
the tpm_struct.parse_errors_total{code} OTel counter bounded.
Features
- Ten registered codes covering every failure class from §8.3 (object attributes), §10.x (attest), §11.x (algorithm and curve), §12.x (public area), and §16 (name).
TpmStructErrorextendsSuaveplanError<TpmStructErrorCode>soinstanceofnarrows the.codeunion.tpmStructError(code, message, detail?)helper attaches a structureddetailpayload (cursor, requested length, Zod issues) to the cause chain so log adapters can format failures without downcasting.
Usage: Basic Example
import {
TPM_STRUCT_CODES,
TpmStructError,
tpmStructError,
} from "@suaveplan/tpm-struct/errors";
try {
// ... parser code
} catch (e) {
if (e instanceof TpmStructError) {
console.error(`tpm-struct failure: ${e.code}`);
if (e.code === TPM_STRUCT_CODES.TRUNCATED) {
// recoverable: ask the upstream for a longer buffer
}
}
}
void tpmStructError;
Usage: Advanced Example
import {
TPM_STRUCT_CODES,
TpmStructError,
} from "@suaveplan/tpm-struct/errors";
type ParseFailureMetric = "magic" | "truncated" | "alg" | "curve" | "other";
function classify(err: TpmStructError): ParseFailureMetric {
switch (err.code) {
case TPM_STRUCT_CODES.MAGIC_INVALID:
return "magic";
case TPM_STRUCT_CODES.TRUNCATED:
return "truncated";
case TPM_STRUCT_CODES.ALG_UNSUPPORTED:
return "alg";
case TPM_STRUCT_CODES.CURVE_UNSUPPORTED:
return "curve";
default:
return "other";
}
}
// `cause.detail` carries the structured failure context.
function reportTruncated(err: TpmStructError) {
const detail =
((err as unknown as { cause?: { detail?: Record<string, unknown> } })
.cause?.detail) ?? {};
return { cursor: detail.cursor, requested: detail.requested };
}
API Reference
TPM_STRUCT_CODES— frozen registry:MAGIC_INVALID,TRUNCATED,ALG_UNSUPPORTED,CURVE_UNSUPPORTED,TYPE_MISMATCH,MALFORMED,NAME_ALG_NULL,ATTEST_TYPE_UNSUPPORTED,PARAMETERS_INVALID,OBJECT_ATTRIBUTES_RESERVED_NONZERO. Each value is the literalTPM_STRUCT.<NAME>.TpmStructError— base class, message is always prefixed with the code literal.TpmStructErrorCode— literal union of the ten code strings.tpmStructError(code, message, detail?)— convenience constructor;detail(when provided) is wrapped in an Error so it survives through thecausechain.
Implementation Notes
The error message is always prefixed with the code literal so log
scrapers find a stable substring without inspecting .code. Non-Error
detail payloads are wrapped in a synthetic Error carrying a detail
slot — this preserves the standard ECMAScript Error.cause shape while
still surfacing structured fields downstream code can read.