3.2 KiB
@suaveplan/license — error-codes
Purpose
This module owns the stable error-code registry for @suaveplan/license. It
exposes LICENSE_CODES (a frozen defineCodes("LICENSE", [...]) record),
the LicenseErrorCode type union, and the LicenseError class. Every
public failure path in the package raises a LicenseError carrying one of
these twelve namespaced LICENSE.* codes, so consumers can dispatch on the
literal string or instanceof LicenseError and let TypeScript narrow the
union exhaustively.
Features
- 12 codes covering input validation, encoding / parsing, cryptographic
failures, lifecycle (expired / revoked), manager state, feature-mask
bounds, and
AbortSignalcancellation. LicenseErrorextendsSuaveplanError<LicenseErrorCode>so the genericcodetype narrows underinstanceof.- Constructor widened to
publicso all modules can construct errors directly without trampolines. - Codes are namespaced
LICENSE.*per the suaveplan-wide pattern (see@suaveplan/crypto-keys'sCHAIN_KEYS.*), making programmatic dispatch consistent across packages.
Usage: Basic
import { LicenseError, LICENSE_CODES } from "@suaveplan/license/error-codes/error-codes";
throw new LicenseError(
LICENSE_CODES.INVALID_ENCODING,
"Invalid Base32 character: !"
);
Usage: Advanced
Attach a Zod cause and structured context for an input-validation
boundary failure:
import { LicenseError, LICENSE_CODES } from "@suaveplan/license/error-codes/error-codes";
import { LicensePayloadSchema } from "@suaveplan/license/schemas/schemas";
try {
LicensePayloadSchema.parse(input);
} catch (zodError) {
throw new LicenseError(
LICENSE_CODES.INVALID_INPUT,
"License payload failed schema validation",
{ cause: zodError, context: { source: "generateLicense" } }
);
}
Consumer-side narrowing:
import { LicenseError } from "@suaveplan/license";
try {
await manager.generate({ productId: 1 });
} catch (error) {
if (error instanceof LicenseError && error.code === "LICENSE.NO_SIGNING_KEY") {
// recover or re-prompt
} else {
throw error;
}
}
API Reference
LICENSE_CODES
Frozen Readonly<Record<Reason, "LICENSE.<Reason>">> where Reason is
one of the 12 keys: INVALID_INPUT, INVALID_ENCODING, MALFORMED,
UNSUPPORTED_VERSION, UNKNOWN_SIGNING_KEY, INVALID_SIGNATURE,
EXPIRED, REVOKED, NO_SIGNING_KEY, FEATURE_INDEX_OUT_OF_RANGE,
PAYLOAD_OUT_OF_RANGE, ABORTED.
type LicenseErrorCode
String-literal union of all 12 namespaced codes.
class LicenseError extends SuaveplanError<LicenseErrorCode>
Concrete error class. Constructor: (code, message, options?) where
options is SuaveplanErrorOptions (carries optional cause,
context, traceId, clock).
Implementation Notes
The registry uses defineCodes from @suaveplan/error so the type of
LICENSE_CODES.INVALID_ENCODING is the literal "LICENSE.INVALID_ENCODING"
(not the broad string), giving exhaustiveness checking in switch
statements. The list is declared as const so TypeScript captures the
tuple shape and the helper's mapped-type return picks every key.