flexway
FRENTalk to an expert

Errors

ReferenceDevelopersSince version 0.1.0

Markdown

On this page

A refusal always carries a stable code to switch on. The same code crosses REST, gRPC, MCP and the asynchronous channels.

Product side: API gateway; operations side: Troubleshooting.

The format

{
  "type": "https://flexway.dev/problems/upstream_timeout",
  "title": "The upstream did not answer within its budget",
  "status": 504,
  "detail": "Operation getOrder exceeded its 2s budget.",
  "instance": "/orders/42",
  "code": "upstream_timeout",
  "request_id": "01J9Z2K7QWE",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}

Switch on code (or on type, which the operator may redirect to its portal), never on title or detail. An error never holds the API's internal message, a host name or personal data.

The codes

Status code Who acts
400 malformed_request You: unreadable request or undeclared parameter
401 unauthenticated You: credential missing or invalid
403 forbidden You: scope, role or tenant insufficient
404 not_found You: undeclared route
405 method_not_allowed You: see Allow
412 precondition_failed You: If-Match not met, or SSE resumption beyond the history
413 payload_too_large You
415 unsupported_media_type You: see Accept
422 invalid_request You: see errors
428 idempotency_key_required You: add Idempotency-Key
429 rate_limited You: slow down, see Retry-After
429 quota_exceeded You: the daily or monthly quota is spent
500 internal_error The gateway
502 upstream_error The API
502 response_too_large The API
503 upstream_unavailable The API: retry after Retry-After
503 overloaded The platform: retry after Retry-After
504 upstream_timeout The API: unknown outcome for a write
per the API upstream_status The API: an error of a gRPC upstream, or a status the operator translated

400 says "I could not read it", 422 "I read it, and it is wrong"; 429 is your rate, 503 our capacity; 502 an unusable answer, 504 no answer in time.

On the other surfaces

Surface Representation
/v1/* (inference) OpenAI's envelope: unauthenticated -> authentication_error, forbidden -> permission_error, rate_limited -> rate_limit_error, invalid_request -> invalid_request_error; the gateway's code is kept (inference)
gRPC google.rpc.Status, ErrorInfo.reason = the code (gRPC)
MCP An isError result carrying the problem (MCP)
SSE, WebSocket event: error or a last message, then the close (asynchronous channels)

Next steps