5.2 KiB
serialize-error
Purpose
Defines the error hierarchy for @suaveplan/serialize. All errors thrown by this package extend SerializationError, which in turn extends SuaveplanError from @suaveplan/error. This design ensures every thrown error carries a stable, machine-readable code string (SERIALIZE.*) so callers can programmatically distinguish between circular references, depth overflows, size overflows, and unknown type tags without parsing human-readable messages.
The contextual payload (SerializationErrorContext) transports structural metadata — tag names, recursion depths, byte sizes, and dot-path strings — that would otherwise require expensive re-traversal to reconstruct after the fact.
Features
SerializationError— base class; extendsSuaveplanError<SerializationErrorCode>with an optionalSerializationErrorContextCircularReferenceError— emitted when a cycle is detected in the input object graph; includes the dot-path where the cycle was encounteredMaxDepthExceededError— emitted when recursion depth exceeds the caller-configuredmaxDepth; includes the depth valueMaxSizeExceededError— emitted when the serialized byte count exceedsmaxSize; includes the approximate size in bytesUnsupportedTypeError— emitted during deserialization when a__ttag has no registered decoder; includes the unknown tag string- Exported
SerializationErrorCodeunion type for exhaustiveswitchnarrowing - Re-exported
SERIALIZE_CODESconstant map for use in tests and error construction
Usage: Basic Example
import {
CircularReferenceError,
MaxDepthExceededError,
SerializationError,
} from "@suaveplan/serialize";
try {
// serialization call here
} catch (err) {
if (err instanceof CircularReferenceError) {
console.error("Cycle at", err.context?.path);
} else if (err instanceof SerializationError) {
console.error("Serialization failed:", err.code);
}
}
Usage: Advanced Example
import {
SERIALIZE_CODES,
SerializationError,
UnsupportedTypeError,
type SerializationErrorCode,
} from "@suaveplan/serialize";
function handleSerializeError(err: unknown): never {
if (!(err instanceof SerializationError)) throw err;
const code: SerializationErrorCode = err.code;
switch (code) {
case SERIALIZE_CODES["CODEC.CIRCULAR_REFERENCE"]:
throw new Error(`Cycle at path: ${err.context?.path ?? "unknown"}`);
case SERIALIZE_CODES["CODEC.MAX_DEPTH"]:
throw new Error(`Too deep: ${err.context?.depth}`);
case SERIALIZE_CODES["CODEC.MAX_SIZE"]:
throw new Error(`Too large: ${err.context?.size} bytes`);
case SERIALIZE_CODES["CODEC.UNKNOWN_TAG"]:
throw new Error(`No decoder for tag: ${err.context?.tag}`);
default:
throw err;
}
}
// UnsupportedTypeError carries the unknown tag
const e = new UnsupportedTypeError("__MyCustomClass");
console.log(e.context?.tag); // "__MyCustomClass"
API Reference
SerializationError
class SerializationError extends SuaveplanError<SerializationErrorCode> {
constructor(
code: SerializationErrorCode,
messageKey: string,
options?: SerializationErrorOptions,
): void
}
code— one of theSERIALIZE.*codesmessageKey— i18n key resolved via@suaveplan/errorresolveroptions.cause— underlying error, chained viaError.causeoptions.context—SerializationErrorContextmetadata
CircularReferenceError
new CircularReferenceError(path?: string, cause?: unknown)
Code: SERIALIZE.CODEC.CIRCULAR_REFERENCE. context.path is the dot-path string where the cycle was detected.
MaxDepthExceededError
new MaxDepthExceededError(depth: number, cause?: unknown)
Code: SERIALIZE.CODEC.MAX_DEPTH. context.depth is the depth value at which encoding was aborted.
MaxSizeExceededError
new MaxSizeExceededError(size: number, cause?: unknown)
Code: SERIALIZE.CODEC.MAX_SIZE. context.size is the approximate byte count.
UnsupportedTypeError
new UnsupportedTypeError(tag: string, cause?: unknown)
Code: SERIALIZE.CODEC.UNKNOWN_TAG. context.tag is the unrecognised tag string.
SerializationErrorContext
interface SerializationErrorContext {
tag?: string;
depth?: number;
size?: number;
path?: string;
}
SerializationErrorOptions
interface SerializationErrorOptions {
cause?: unknown;
context?: SerializationErrorContext;
}
SerializationErrorCode
Union type of all SERIALIZE.* code strings; use with exhaustive switch statements.
Implementation Notes
SerializationErrormapsSerializationErrorOptions.contextto the genericRecord<string, unknown>shape expected bySuaveplanErrorOptionswithout widening the exported interface — callers always get the narrowSerializationErrorContexttype.- Each subclass uses a specific constructor signature (only the meaningful fields, not the full code/key/options triple) to make throw sites readable and to prevent code/message mismatches.
- The
SERIALIZE_CODESconstant is defined in a separatecodes.tsmodule and re-exported from here so that the error file is self-contained for consumers who only import errors.