Files
restloom/docs/errors.md
T

68 lines
3.5 KiB
Markdown

# Errors
Every error is a JSON object with a stable code, and a message naming the part of the request at fault when there is one:
```json
{ "error": "unknown_column", "message": "password_hash" }
```
A message never contains SQL or database text.
## The request
| Code | Status | Means |
|---|---|---|
| `not_found` | 404 | no such resource, or no such row, or a row you may not see |
| `method_not_allowed` | 405 | the resource does not allow this method, or a procedure was not called with POST |
| `unknown_column` | 400 | the column does not exist or is hidden |
| `unknown_relation` | 400 | the relation does not exist |
| `unknown_operator` | 400 | the operator is not one of `eq neq gt gte lt lte in like ilike match imatch is ov cs cd` |
| `bad_operator` | 400 | the operator does not apply to the column's type |
| `invalid_value` | 400 | the value does not fit the column's type |
| `bad_filter` | 400 | a filter is not `operator.value` |
| `bad_logic` | 400 | an `or` or `and` is not `(term,term)` |
| `bad_list` | 400 | an `in` list is malformed, empty, or too long |
| `bad_name` | 400 | a dotted or quoted name is malformed |
| `bad_syntax` | 400 | unbalanced quotes or parentheses |
| `bad_select` | 400 | a select item is malformed |
| `duplicate_select` | 400 | a name is selected twice |
| `unknown_aggregate` | 400 | not one of `count sum avg min max` |
| `bad_aggregate` | 400 | the aggregate does not apply to the column's type |
| `aggregate_with_embed` | 400 | a grouped read cannot embed relations |
| `aggregate_in_embed` | 400 | an embed cannot hold aggregates |
| `bad_order` | 400 | an order term names a to-many column, an unorderable type, or, in a grouped read, an unselected column |
| `not_embedded` | 400 | `relation.order`, `.limit` or `.offset` names a relation that is not embedded |
| `too_deep` | 400 | a path or an embed walks more relations than `limits.depth` |
| `too_many_filters` | 400 | more filters than `limits.filters` |
| `bad_limit`, `bad_offset` | 400 | not a whole number |
| `limit_exceeded` | 400 | a limit over `limits.maxPage` |
| `bad_count` | 400 | `count` is not `exact` or `estimated` |
| `unsupported` | 400 | the database cannot do what was asked, e.g. a regular expression on SQLite |
## Writes and procedures
| Code | Status | Means |
|---|---|---|
| `bad_body` | 400 | the body is not an object or a list of objects within `limits.bodyRows` |
| `body_too_large` | 413 | the body is over the adapter's size limit |
| `mixed_columns` | 400 | the rows of a body name different columns |
| `not_writable` | 400 | the column cannot be written by this method |
| `filter_required` | 400 | a bulk update or delete has no filter |
| `out_of_scope` | 403 | a value contradicts the host's scope |
| `unknown_argument` | 400 | the procedure's function takes no argument of that name |
| `missing_argument` | 400 | an argument without a default is missing |
| `bad_argument` | 400 | a GET procedure's argument is given twice |
## The database
| Code | Status | Means |
|---|---|---|
| `duplicate` | 409 | a unique constraint refused the row |
| `reference_missing` | 409 | a foreign key points to a row that does not exist |
| `still_referenced` | 409 | the row is still referenced by another |
| `value_required` | 400 | a required column has no value |
| `value_rejected` | 400 | a check constraint refused the value |
| `forbidden` | 403 | the database refused the session's role |
| `timeout` | 503 | the statement ran past `limits.timeoutMs` |
| `internal` | 500 | anything else; your `onError` hook receives it |