ALLM.Error.ClassificationAdapterError exception (allm v0.6.1)

Copy Markdown View Source

Errors returned by typed-classification adapters.

Layer A — serializable (no PIDs, refs, funs, or raw API keys). Closed-enum exception struct carrying nine reasons: the moderation enum minus :unsupported_feature and :batch_too_large. A classification request has no optional fields an adapter could fail to express, and questions are not chunked across calls, so neither atom has anywhere to fire.

Error reasons

ReasonHTTP statusFires when
:authentication_failed401/403API key missing or invalid. Surface to the user; no retry.
:rate_limited429Provider quota exceeded; :retry_after_ms populated when a Retry-After header is present. Retried automatically.
:invalid_request400/404/422The provider rejected the body (for example an unknown model); an empty :questions map reaching a direct adapter call; a body that cannot be JSON-encoded; or a question over a provider limit, with :metadata naming the question and the limit. Fix the request; no retry.
:context_length_exceeded400The state plus the longest question exceeds the model's token budget. Shrink the state; no retry.
:provider_unavailable500/502/503/504/529Provider server-side failure or overload. Retried automatically.
:timeout—Adapter request_timeout exceeded. Retried automatically.
:network_error—TCP/TLS/DNS failure. Retried automatically.
:malformed_response—200 with an unparseable body, a missing answers object, an answer for an id that was not asked, a requested id with no answer, or an answer whose type differs from its question's. No retry; report it to the provider.
:unknownanyCatch-all for shapes the adapter cannot classify; non-retryable.

:cause stays encodable

Like its siblings this struct implements Jason.Encoder, so an adapter must never store a raw exception in :cause: an exception can carry the caller's data or a pid, and would make the error itself unencodable. Report the condition as data instead — a body that cannot be encoded is reason: :invalid_request with metadata: %{cause: :unencodable_body}, not the exception that the encoder raised.

Summary

Types

Closed set of classification-adapter error reasons.

t()

Functions

Return the closed list of legal :reason atoms.

Build a %ClassificationAdapterError{} from a reason atom and optional keyword fields.

Types

reason()

@type reason() ::
  :authentication_failed
  | :rate_limited
  | :invalid_request
  | :context_length_exceeded
  | :provider_unavailable
  | :timeout
  | :network_error
  | :malformed_response
  | :unknown

Closed set of classification-adapter error reasons.

t()

@type t() :: %ALLM.Error.ClassificationAdapterError{
  __exception__: true,
  cause: term() | nil,
  message: String.t(),
  metadata: map(),
  provider: atom() | nil,
  reason: reason(),
  retry_after_ms: non_neg_integer() | nil,
  status: pos_integer() | nil
}

Functions

new(reason, opts \\ [])

@spec new(
  reason(),
  keyword()
) :: t()

Build a %ClassificationAdapterError{} from a reason atom and optional keyword fields.

opts may include :message, :provider, :status, :retry_after_ms, :cause, and :metadata. When :message is omitted, the default is "classification adapter error: #{reason}" — with a provider suffix "classification adapter error (#{provider}): #{reason}" when :provider is set.

Raises ArgumentError if reason is not one of the atoms in the closed reason/0 enum.

Examples

iex> err = ALLM.Error.ClassificationAdapterError.new(:timeout)
iex> err.reason
:timeout
iex> Exception.message(err)
"classification adapter error: timeout"

iex> err = ALLM.Error.ClassificationAdapterError.new(:provider_unavailable, provider: :typesafe, status: 529)
iex> Exception.message(err)
"classification adapter error (typesafe): provider_unavailable"