Files
skills/docs/commerce/contacts/api-plugin-contacts/src/error-codes/error-codes.md
2026-05-29 08:20:56 +01:00

3.3 KiB

error-codes — stable CONTACTS_API.* registry

(no submodules)

Purpose

Single source of truth for every failure path inside @suaveplan/api-plugin-contacts. Built on the suaveplan @suaveplan/error foundation (defineCodes + SuaveplanError) so codes are typed as a string-literal union and the registry is wire- stable across versions. Consumers (UI translation layers, response encoders, log shippers) branch on error.code without sniffing the message text.

The 12 codes split cleanly into three groups: lifecycle errors (INVALID_INPUT, SERVICE_NOT_AVAILABLE, SCHEMA_APPLY_FAILED, ROUTE_PREFIX_COLLISION), boundary errors visible to HTTP callers (NOT_FOUND, UNAUTHORIZED, IMPORT_TOO_LARGE), and operation errors raised by the SurrealDB repositories (CREATE_FAILED, UPDATE_FAILED, DELETE_FAILED, GROUP_DEPTH_EXCEEDED, MEMBERSHIP_EXISTS).

Features

  • Stable code strings prefixed with CONTACTS_API. (built via defineCodes) — safe to log or send to clients.
  • ContactsApiError subclass of SuaveplanError preserves the underlying cause, optional structured context, and a redactable message.
  • Codes are exhaustive: every throw in the production tree uses exactly one of the 12; the spec-conformance test pins this.

Usage: Basic

import {
    CONTACTS_API_CODES,
    ContactsApiError,
} from "@suaveplan/api-plugin-contacts";

throw new ContactsApiError(
    CONTACTS_API_CODES.NOT_FOUND,
    "contact not found",
    { context: { statusCode: 404 } }
);

Usage: Advanced

import {
    CONTACTS_API_CODES,
    type ContactsApiErrorCode,
    ContactsApiError,
} from "@suaveplan/api-plugin-contacts";

function toHttpStatus(code: ContactsApiErrorCode): number {
    switch (code) {
        case CONTACTS_API_CODES.NOT_FOUND:
            return 404;
        case CONTACTS_API_CODES.UNAUTHORIZED:
            return 401;
        case CONTACTS_API_CODES.IMPORT_TOO_LARGE:
        case CONTACTS_API_CODES.GROUP_DEPTH_EXCEEDED:
        case CONTACTS_API_CODES.INVALID_INPUT:
            return 400;
        case CONTACTS_API_CODES.MEMBERSHIP_EXISTS:
            return 409;
        default:
            return 500;
    }
}

try {
    /* … */
} catch (err) {
    if (err instanceof ContactsApiError) {
        return Response.json(
            { success: false, code: err.code, error: err.message },
            { status: toHttpStatus(err.contactsApiCode) }
        );
    }
    throw err;
}

API Reference

  • CONTACTS_API_CODES — frozen registry returned by defineCodes("CONTACTS_API", [...]).
  • ContactsApiErrorCode — string-literal union of every member of CONTACTS_API_CODES.
  • class ContactsApiError extends SuaveplanError<ContactsApiErrorCode> — constructor (code, message, options?). Stores the original code on contactsApiCode for ergonomic narrowing.

Implementation Notes

  • The registry is declared as const; defineCodes returns the frozen mapping ({ CODE: "CONTACTS_API.CODE", … }) so callers cannot accidentally mutate it.
  • The constructor delegates to SuaveplanError, which threads cause, context, and a default name through. No code path here re-implements that — adding a new code only requires adding a string literal to the as const array.