first commit
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# error-codes — stable CONTACTS_API.* registry
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user