3.4 KiB
error-codes
(no submodules)
Purpose
Stable error-code registry for @suaveplan/api-plugin-payment. Every failure path in the plugin raises a PaymentPluginError that carries one of 15 PAYMENT_PLUGIN.* codes. The registry gives consumers a small, well-documented enum to programmatically branch on without inspecting human-readable messages — exactly the contract every other @suaveplan/api-plugin-* package follows.
The module also exports the PaymentPluginError class, which extends SuaveplanError<PaymentPluginErrorCode> so instanceof PaymentPluginError narrows code to the typed enum at the call site. The class preserves the supplied code on the discriminant pluginCode field for compatibility with downstream error handlers that match on a package-specific property name (the auth plugin uses authCode, the openapi plugin uses openapiCode — this package uses pluginCode).
Features
- 15 namespaced codes under
PAYMENT_PLUGIN.covering input validation, ownership/anti-enumeration, provider failures, webhook signature/timestamp, idempotency conflict, state-machine, amount/currency mismatch, refund-exceeds-captured, configuration, and service-registry plumbing. - Typed
PaymentPluginErrorContextcarryingstatusCode,intentId,ownerId,missing[],prefix,currency,expectedCurrencyfor diagnostic plumbing. PaymentPluginErrordiscriminant class withpluginCodeand the standardSuaveplanErrorcause-chain,toJSON,toProblemJSON, and OTel span-event hooks.
Usage: Basic
import {
PAYMENT_PLUGIN_CODES,
PaymentPluginError,
} from "@suaveplan/api-plugin-payment";
throw new PaymentPluginError(
PAYMENT_PLUGIN_CODES.NOT_FOUND,
'Payment intent "abc" not found',
{ context: { statusCode: 404, intentId: "abc" } }
);
Usage: Advanced
try {
await service.captureIntent({ id, ownerId, amount });
} catch (err) {
if (err instanceof PaymentPluginError) {
switch (err.pluginCode) {
case PAYMENT_PLUGIN_CODES.NOT_FOUND:
return c.json({ error: "not_found" }, 404);
case PAYMENT_PLUGIN_CODES.CURRENCY_MISMATCH:
case PAYMENT_PLUGIN_CODES.AMOUNT_MISMATCH:
return c.json({ error: err.pluginCode }, 422);
case PAYMENT_PLUGIN_CODES.IDEMPOTENCY_CONFLICT:
return c.json({ error: "conflict" }, 409);
}
}
throw err;
}
API Reference
PAYMENT_PLUGIN_CODES—defineCodes("PAYMENT_PLUGIN", [...])const-object.PaymentPluginErrorCode— union of the 15PAYMENT_PLUGIN.*strings.PaymentPluginErrorContext— optional discriminant fields carried alongside the baseSuaveplanErrorcontext.PaymentPluginError extends SuaveplanError<PaymentPluginErrorCode>—pluginCode: PaymentPluginErrorCode.
Implementation Notes
The 15-code count matches the proposal's spec delta. Removing a code (because no production call site currently uses it) is banned by AGENTS.md §2c — codes are part of the public API contract and unused-looking codes get wired into call sites that didn't exist yet (e.g. PROVIDER_NOT_CONFIGURED covers a programmatic mis-wire pattern callers do hit during initial integration). The conformance test in api-plugin-payment.spec-conformance.test.ts proves every code is reachable from a non-test call site.