Errors across the wire
A failed call answers with an envelope { ok: false, error } and the status of the error, so fetch tools, proxies and logs see the real status.
A failed call answers with an envelope { ok: false, error } and the status of the error, so fetch tools,
proxies and logs see the real status. What the error says depends on who is allowed to read it.
| Thrown on the server | Status | In production the client gets | Reported to onError |
|---|---|---|---|
ValidationError |
400 | HttpError 400, data.issues |
no |
HttpError 4xx |
its status | HttpError with its message and data |
no |
HttpError 5xx |
its status | HttpError with the standard reason phrase (Bad Gateway) and no data, unless expose: true |
yes |
notFound() |
404 | the router's notFound() signal |
no |
redirect() |
200 | the router's redirect() signal (next section) |
no |
| an abort error | 499 | ServerFnError |
no |
| any other value | 500 | ServerFnError with Internal Server Error |
yes |
HttpError takes an optional data payload for the caller and expose to override
the default (true below 500). The message of an unexpected error never leaves the server in production. With
dev: true (the dev server) the message is shown as Name: message, and an HttpError shows its message and
data whatever its status. Every error carries requestId, the id the server logged: it is the x-request-id
response header and info.event.id in onError, so a user's report finds the log line.
On the client, ServerFnError has status and requestId. A
ServerFnProtocolError means the answer was not a server
function answer at all (an HTML page from a proxy, a truncated body, a redirect the browser did not follow, an
unknown shape); the call may or may not have run.