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
| Reason | HTTP status | Fires when |
|---|---|---|
:authentication_failed | 401/403 | API key missing or invalid. Surface to the user; no retry. |
:rate_limited | 429 | Provider quota exceeded; :retry_after_ms populated when a Retry-After header is present. Retried automatically. |
:invalid_request | 400/404/422 | The 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_exceeded | 400 | The state plus the longest question exceeds the model's token budget. Shrink the state; no retry. |
:provider_unavailable | 500/502/503/504/529 | Provider 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. |
:unknown | any | Catch-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
Functions
Return the closed list of legal :reason atoms.
Build a %ClassificationAdapterError{} from a reason atom and optional
keyword fields.
Types
@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.
@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
@spec legal_reasons() :: [reason()]
Return the closed list of legal :reason atoms.
Examples
iex> :provider_unavailable in ALLM.Error.ClassificationAdapterError.legal_reasons()
true
iex> length(ALLM.Error.ClassificationAdapterError.legal_reasons())
9
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"