Errors
The Accord API follows the GraphQL error convention: a valid GraphQL
operation returns HTTP 200, and any errors appear in the response
body's errors array alongside (possibly partial) data.
Response shape
{
"data": null,
"errors": [
{
"message": "permission denied for relation accord",
"locations": [{ "line": 2, "column": 3 }],
"path": ["accords"],
"extensions": {
"code": "42501",
"severity": "ERROR"
}
}
]
}
Field by field:
| Field | Meaning |
|---|---|
message | Human-readable description. Don't pattern-match on this; it can change. |
path | The response path the error applies to. |
locations | Where in the query string the error originated. |
extensions.code | Stable, machine-readable code (see below). |
extensions.severity | ERROR, WARNING, etc. |
Common error codes
These are PostgreSQL error codes surfaced through the GraphQL layer:
| Code | Meaning | Typical cause |
|---|---|---|
42501 | Permission denied | The key's role can't see or change this row/table. |
23505 | Unique violation | A row with the same unique value already exists. |
23503 | Foreign-key violation | Referenced row doesn't exist or has been deleted. |
23502 | Not-null violation | A required column wasn't provided. |
22P02 | Invalid input syntax | A UUID, enum, or date was malformed. |
P0001 | Application error | A server-side business rule rejected the request. Check message. |
HTTP-level errors
A non-200 response means something failed outside of GraphQL: bad
JSON, missing or invalid Authorization header, the endpoint being
unreachable, etc. In that case there is no GraphQL errors array; check
the response status and body directly.
| Status | Meaning |
|---|---|
400 | Malformed request (invalid JSON, missing query). |
401 | Missing or invalid API key. |
403 | API key recognized but not authorized for the request. |
5xx | Server-side problem. Retry with exponential backoff. |
Partial success
When a query selects multiple fields and one fails, GraphQL can return
both data (with the fields that succeeded) and errors (for the ones
that didn't). Always check both:
const { data, errors } = await response.json();
if (errors) {
for (const err of errors) {
console.error(err.extensions?.code, err.message, err.path);
}
}
if (data) {
// Some fields may still be usable.
}
Retries
Retry on transient HTTP errors (5xx) with exponential backoff. Don't
retry blindly on GraphQL errors; most are deterministic and will
reproduce on the next call.