Skip to content

Error Handling Internals

ProxAI keeps internal errors strongly typed, then projects them into compact client-facing HTTP or SSE errors. The projection boundary is centralized so provider, upstream, and translation code do not each invent their own response format.

Typed error
Core IngressError/TranslationError plus application RequestError/InternalError/UpstreamError
error/render.rs
Maps domain errors into ErrorResponseSpec
ErrorResponseFields
Shared HTTP/SSE status + payload fields
Client response
HTTP text/json response or SSE error event bytes
Error typeMeaning
JsonPayloadErrorShared core JSON path/location/source details
IngressErrorCore structured request normalization or validation failure
RequestErrorApplication body/path failure or wrapped IngressError
ConfigErrorConfig loading and config-file reads
InternalErrorRuntime invariants, local IO, JSON serialization, internal body reads
UpstreamErrorUpstream send/status/body-read failures
TranslationErrorCore non-streaming protocol payload conversion failures
StreamTranslationErrorCore structured stream conversion and lifecycle semantics
SseErrorApplication SSE carrier parsing
ByteStreamErrorStream carrier failures

Core domain errors are returned through Result and transparently wrapped by application errors so their source chains remain intact. Non-fatal adaptations use Observation instead; do not emit and return the same failure twice.

Do not hide semantic stream or HTTP failures inside std::io::Error; reserve IO errors for real OS/filesystem IO.

JSON format wraps a compact error payload:

{
    error:{
      message:"quota exhausted",
      type:"upstream_error",
      code:"rate_limit_exceeded",
      param:"input",
      status:429
    }
}

Text format returns the same compact error object as pretty-printed JSON with text/plain, which keeps raw clients readable while preserving upstream code and param details.

For upstream non-2xx responses, ProxAI keeps useful details when the upstream actually provides them:

  • Retry-After
  • upstream request id headers
  • rate-limit headers
  • OpenAI-style code
  • OpenAI-style param
  • Anthropic error.type, normalized as the provider error code

proxai-core::provider::normalize_provider_error owns structured JSON error normalization. The application keeps HTTP status/headers, body bytes, empty/non-JSON handling, and client-facing rendering. It should not fabricate upstream code or param values. These rules implement Behavior Contract C15 and C18.