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 internal error
RequestError, ConfigError, InternalError, UpstreamError, TranslationError, SSE errors
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
RequestErrorInbound body or validation failure
ConfigErrorConfig loading and config-file reads
InternalErrorRuntime invariants, local IO, JSON serialization, internal body reads
UpstreamErrorUpstream send/status/body-read failures
TranslationErrorProtocol payload conversion failures
SseError / SseTranslationErrorSSE event semantics
ByteStreamErrorStream carrier failures

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 only the human-readable message, which is the default for Zed readability.

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

It should not fabricate upstream code or param values. These rules implement Behavior Contract C15 and C18.