4.3 KiB
codes
(no submodules)
Purpose
Defines the stable, namespaced error-code registry for @suaveplan/crypto-utils. Every error thrown by this package carries a code from this registry, which lets callers type-narrow on error.code rather than relying on string matching against message text.
Features
- Single
defineCodescall produces a frozen, read-only map of codes under theCRYPTO.UTILSnamespace - Codes are plain string literals (
"CRYPTO.UTILS.PRIMITIVE_NOT_IMPLEMENTED", etc.) — safe to log, serialize, and compare across process boundaries CryptoUtilsCodeunion type keeps downstreamcatchblocks fully typed without any runtime cost- Covers the full error surface of the package: encoding validation, byte-length mismatches, integer-range checks, Merkle-tree errors, RNG limits, and the primitive-not-implemented sentinel
Usage: Basic Example
import { CRYPTO_UTILS_CODES, type CryptoUtilsCode } from "@suaveplan/crypto-utils/errors/codes";
function handleError(code: CryptoUtilsCode): string {
switch (code) {
case CRYPTO_UTILS_CODES.ENCODING_INVALID_INPUT:
return "The supplied string is not valid for the chosen encoding.";
case CRYPTO_UTILS_CODES.PRIMITIVE_NOT_IMPLEMENTED:
return "This cryptographic primitive has no native implementation yet.";
default:
return "Unknown crypto-utils error.";
}
}
Usage: Advanced Example
Type-narrowing in a catch block using the CryptoUtilsCode union:
import { CRYPTO_UTILS_CODES, type CryptoUtilsCode } from "@suaveplan/crypto-utils/errors/codes";
import { CryptoUtilsError } from "@suaveplan/crypto-utils/errors/crypto-utils-error";
async function safeHex(input: string): Promise<Uint8Array | null> {
try {
const { hexToBytes } = await import("@suaveplan/crypto-utils/encoding/hex/hex");
return hexToBytes(input);
} catch (err) {
if (err instanceof CryptoUtilsError) {
const code: CryptoUtilsCode = err.code;
if (code === CRYPTO_UTILS_CODES.ENCODING_INVALID_INPUT) {
console.warn("Bad hex input, returning null:", err.message);
return null;
}
}
throw err;
}
}
API Reference
CRYPTO_UTILS_CODES
const CRYPTO_UTILS_CODES: {
readonly PRIMITIVE_NOT_IMPLEMENTED: "CRYPTO.UTILS.PRIMITIVE_NOT_IMPLEMENTED";
readonly ENCODING_INVALID_INPUT: "CRYPTO.UTILS.ENCODING.INVALID_INPUT";
readonly BYTES_LENGTH_MISMATCH: "CRYPTO.UTILS.BYTES.LENGTH_MISMATCH";
readonly BYTES_INVALID_LENGTH: "CRYPTO.UTILS.BYTES.INVALID_LENGTH";
readonly INTEGER_OUT_OF_RANGE: "CRYPTO.UTILS.INTEGER.OUT_OF_RANGE";
readonly MERKLE_EMPTY_LEAVES: "CRYPTO.UTILS.MERKLE.EMPTY_LEAVES";
readonly MERKLE_INVALID_PROOF: "CRYPTO.UTILS.MERKLE.INVALID_PROOF";
readonly RNG_INVALID_LENGTH: "CRYPTO.UTILS.RNG.INVALID_LENGTH";
};
Frozen registry produced by defineCodes("CRYPTO.UTILS", [...]). Dot-separated sub-namespaces (ENCODING.INVALID_INPUT, BYTES.LENGTH_MISMATCH, etc.) become underscore-keyed properties on the returned object.
Returns — A read-only record whose values are opaque string literals suitable for stable logging and wire serialization.
CryptoUtilsCode
type CryptoUtilsCode = (typeof CRYPTO_UTILS_CODES)[keyof typeof CRYPTO_UTILS_CODES];
Union of every string literal in CRYPTO_UTILS_CODES. Use this as the code parameter type in catch blocks or error-handler signatures to stay fully typed without importing the entire error object.
Implementation Notes
defineCodes (from @suaveplan/error) is the single source of truth for code formatting: it prepends the namespace, freezes the resulting object, and guarantees that each value is a unique string. This file owns no logic — it is a pure declaration layer.
The dot-notation in the raw array entries ("ENCODING.INVALID_INPUT") is a human-readable convention for grouping related codes within the namespace; the resulting object key uses the underscore-separated form (ENCODING_INVALID_INPUT). Consumers should always reference CRYPTO_UTILS_CODES.* constants rather than the raw string literals so that renames are caught at compile time.
Adding a new code requires only appending a string to the as const array in this file and optionally adding a new subclass to the errors/ directory. No numeric IDs, no registry migrations.