Learn / Errors and failures

The server: what a client is told

A server answers every failure; what it says is chosen so that nothing internal leaks. Over RemoteServer.answer and serveFetch:

On the serverThe client receives
A Source fails with RemoteServerError(message)RemoteReadError, RemoteQueryError or RemoteMutationError with that message: write it for the reader
RemoteServer.refuse(mutation, refusal)a 422 with the refusal (a 409 for a Refusal.taken), which Data.refusal decodes
A writer's RemoteServer.taken(), for a declared insert of a taken ida 409 with the mutation's Taken refusal, naming only the Entity and the id
RemoteServer.forbid(reason?)a 403, _tag: 'Forbidden', with reason only when given
RemoteServer.unauthenticated(reason?) from a resolvera 401, _tag: 'Unauthenticated', with reason only when given
A mutation's input does not decodeInvalid mutation input, and nothing of the schema's message
A field authorize withholdsthe field settled, never why; an id withheld whole reads like an id that does not exist
A Drizzle statement failsDatabase query failed for a read or query, Database write failed for a write; the driver's error goes to StatementFailed
A defect, or a layer or resolver that breaksa 500, Internal error; the cause goes to ServerDefect
A write committed and its answer's read failedthe answer without the rows; the client reads them again (AnswerUnread)
A write committed and its live publish failedthe write's answer; live subscribers do not hear it (PublishFailed)

serveFetch takes diagnostics: (diagnostic, request) => Effect, used for everything that request runs, a broken layer included; without it the reporter in the Effect context is used. See the remote-server Diagnostics and Hardening.