Skip to content

Error Handling

GodeX models every failure as a typed, domain-scoped object so that callers, operators, and log aggregation pipelines all speak the same language. Rather than scattering string messages throughout the codebase, the system defines a single abstract base -- GodeXError -- and four concrete subclasses that map one-to-one with architectural layers. Each error carries a machine-readable code, an HTTP status, a structured context bag, and a millisecond-precision timestamp, making it straightforward to trace failures end-to-end from an upstream provider timeout down to the JSON body returned to the client.

At a Glance

AspectDetail
Base classGodeXError -- abstract, extends Error
Domainsserver, bridge, provider, session
Key fieldsdomain, code, status, context, timestamp
LoggingtoLogEntry() produces a plain-object snapshot
HTTP mappinggodeXErrorToHttp / providerErrorToHttp in server/errors.ts
Error codesCentralised in src/error/codes.ts

Error Class Hierarchy

The abstract GodeXError class is defined at src/error/godex-error.ts:2-35. Every subclass declares a fixed domain string and forwards constructor arguments to the base, which normalises status and context defaults.

Error Domains and Codes

Error codes follow the pattern <domain>.<subdomain>.<specific> and are exported as string constants from src/error/codes.ts:1-52.

Server Domain

Raised during request parsing and configuration validation.

CodeHTTPWhen
server.request.invalid_json400Request body is not valid JSON
server.request.missing_model400Required model field absent
server.request.invalid_parameter400Parameter fails validation
server.provider.not_registered400Referenced provider has no registration

source: src/error/codes.ts:46-51

Bridge Domain

Raised when translating between the OpenAI Responses schema and a provider's native format.

CodeHTTPWhen
bridge.request.unsupported_parameter400Parameter has no provider equivalent
bridge.request.tool_skipped400Tool not supported by provider
bridge.request.unsupported_input_item400Input item type not translatable
bridge.request.unsupported_input_content400Content type not translatable
bridge.request.unsupported_tool400Tool definition not translatable
bridge.response.invalid_output_format400Provider output cannot be mapped back
bridge.stream.*400Stream state-machine violations

source: src/error/codes.ts:3-31

Provider Domain

Raised on upstream HTTP failures; always maps to 502 unless the upstream status carries a specific meaning.

CodeUpstream StatusMapped HTTP
provider.upstream.rate_limit429429
provider.upstream.timeout408408
provider.upstream.server_error>= 500502
provider.upstream.errorother422

source: src/error/codes.ts:33-36, source: src/server/errors.ts:20-44

Session Domain

Raised when managing conversation chains.

CodeHTTPWhen
session.chain.not_found404Previous response ID does not exist
session.chain.cycle_detected400Circular chain reference detected
session.chain.depth_exceeded400Chain exceeds configured max depth
session.chain.unavailable503Session store temporarily unavailable
session.store.conflict409Concurrent write conflict

source: src/error/codes.ts:39-43

Error Propagation Flow

The route-level error handler at src/server/routes/responses/error-handler.ts:12-50 dispatches errors in priority order:

  1. ProviderError -- logged at error level, mapped via providerErrorToHttp.
  2. Other GodeXError -- logged at info level, returned with its own status and code.
  3. Unexpected errors -- logged at error level, masked as 500 server_error.

Subclass Construction

Each subclass adds a typed context interface that captures the information relevant to its domain.

SubclassDefault StatusContext HighlightsSource
ServerError400path, methodsrc/error/server-error.ts:10-27
BridgeError400provider, model, parametersrc/error/bridge-error.ts:11-28
ProviderError502provider, model, upstreamStatus, upstreamBodysrc/error/provider-error.ts:12-29
SessionError400responseId, previousResponseId, maxDepthsrc/error/session-error.ts:11-27

HTTP Mapping

The jsonError helper at src/server/errors.ts:50-63 produces a standard JSON envelope:

json
{
  "error": {
    "code": "server.request.missing_model",
    "message": "Missing required field: model"
  }
}

Provider-specific mapping (providerErrorToHttp) translates upstream HTTP status codes into client-facing equivalents at src/server/errors.ts:20-44.

Structured Logging via toLogEntry

Every GodeXError can produce a serialisable log entry via toLogEntry() at src/error/godex-error.ts:24-34. The standalone toLogEntry(err) overload at line 37 gracefully handles non-GodeXError values by wrapping them in a plain object.

Cross-References

References