ExAgent.Error exception (ExAgent v0.4.1)

Copy Markdown View Source

Normalized error returned by every provider operation.

Providers speak different error dialects; this struct gives callers one vocabulary. The :type classifies what went wrong, :retryable? says whether retrying could plausibly succeed, and :raw always preserves the original body so nothing is lost in translation.

case ExAgent.chat(agent, "hello") do
  {:ok, message} -> message
  {:error, %ExAgent.Error{retryable?: true}} -> retry_with_backoff()
  {:error, %ExAgent.Error{} = error} -> Logger.error(error.message)
end

This is also an exception, so it can be raised where a return value is not available (see ExAgent.Provider.stream/3).

Types

TypeMeaningRetryable
:authBad or missing credentials (401, 403)no
:not_foundUnknown model or resource (404)no
:timeoutRequest timed out (408, transport timeout)yes
:rate_limitRate or quota limit hit (429)yes
:context_lengthInput exceeds the model's context windowno
:invalid_requestMalformed request (other 4xx)no
:invalid_responseThe model's output does not fit the requested schemano
:refusalThe model declined to answerno
:unsupportedThe provider cannot perform this operationno
:serverProvider-side failure (5xx, unexpected response shape)yes for 5xx
:transportConnection-level failureyes

Summary

Functions

Classifies a non-success HTTP response into a normalized error.

Normalizes a Req result into {:ok, body} or {:error, t()}.

Classifies a connection-level failure into a normalized error.

Builds an error that did not originate from an HTTP response.

Builds an error for a success response whose shape the service cannot parse.

Types

t()

@type t() :: %ExAgent.Error{
  __exception__: true,
  message: String.t(),
  provider: module() | nil,
  raw: term(),
  retryable?: boolean(),
  status: pos_integer() | nil,
  type: type()
}

type()

@type type() ::
  :auth
  | :rate_limit
  | :invalid_request
  | :invalid_response
  | :refusal
  | :context_length
  | :unsupported
  | :not_found
  | :server
  | :timeout
  | :transport

Functions

from_http(status, body, provider \\ nil)

@spec from_http(pos_integer(), term(), module() | nil) :: t()

Classifies a non-success HTTP response into a normalized error.

body is preserved verbatim in :raw.

from_result(result, provider \\ nil)

@spec from_result({:ok, Req.Response.t()} | {:error, term()}, module() | nil) ::
  {:ok, term()} | {:error, t()}

Normalizes a Req result into {:ok, body} or {:error, t()}.

Collapses the status/transport dispatch every service would otherwise repeat.

from_transport(reason, provider \\ nil)

@spec from_transport(term(), module() | nil) :: t()

Classifies a connection-level failure into a normalized error.

new(type, message, provider \\ nil)

@spec new(type(), String.t(), module() | nil) :: t()

Builds an error that did not originate from an HTTP response.

Used for capability errors (:unsupported) and local validation failures.

unexpected_response(body, provider \\ nil)

@spec unexpected_response(term(), module() | nil) :: t()

Builds an error for a success response whose shape the service cannot parse.

Retryable - a malformed body is usually a transient provider-side glitch.