thinwrap_llm_error (thinwrap_llm v1.1.0)

View Source

Builders for thinwrap_llm:connector_error/0, the plain map every operation failure is returned as.

Connectors build errors here and fail/1 them; the public thinwrap_llm functions catch that and return {error, Error}. Misuse of the API (a missing config key, a bad enum atom) is not a connector error: it raises badarg.

There is deliberately no top-level retry key: for a vendor HTTP error the raw Retry-After header rides in cause as <<"retryAfter">> and its parsed seconds as <<"retryAfterSeconds">>; the decoded vendor body is <<"raw">>.

Summary

Types

Normalized, cross-provider error classification; the same values as the TypeScript, PHP, Go and Python siblings.

Functions

Every code() value, in declaration order.

The status to classify an embedded error object by: its HTTP status when it carries one, else the status its code / type name stands for (insufficient_quota → 429). undefined when it names nothing known.

The HTTP status an error object delivered inside a 2xx body or a stream frame carries: OpenRouter's post-processing errors put the real status in error.code (e.g. 502, as a number or a three-digit string). Anything else is not a status.

A 2xx response with no decodable JSON body (a proxy or captive-portal HTML page, a truncated read). Without this guard the connector would parse nothing into an empty "successful" result.

Abort the current operation with Error. Only valid inside a call made through thinwrap_llm, which turns it into {error, Error}.

A pre-flight invalid_request (no HTTP round-trip).

A 2xx JSON body that decodes but cannot be a real result (one embedding per input missing, a vector cell that is not a number). Coercing it would hand the caller silently wrong data.

Build an error. Fields may carry status, provider_message, message and cause; message falls back to provider_message, then to a generic text, so it is always present. undefined values are dropped.

parse_retry_after/2 against the current time.

Seconds to wait per RFC 9110: delay-seconds is a non-negative integer, so 1.5 or -5 is ignored; an HTTP-date (IMF-fixdate, RFC 850 or asctime, matched strictly so free text such as tomorrow never reads as a date) gives the time until it, and a date already past means "retry now" (0). Anything else is undefined. NowSecs is Unix seconds.

A stream whose body ended before the provider's terminal event. Every supported provider closes a complete stream with one, so an EOF before it is a truncated answer (dropped connection, proxy timeout), not a short one.

The error for a non-2xx response (or an error object inside a 2xx body or a stream frame, which keeps the status it arrived with). The status-to-code classification and the message are the connector's; this adds the shared Retry-After surfacing.

Types

code()

-type code() ::
          rate_limited | auth_failed | provider_unavailable | invalid_request |
          context_length_exceeded | content_filtered | unknown.

Normalized, cross-provider error classification; the same values as the TypeScript, PHP, Go and Python siblings.

Functions

codes()

-spec codes() -> [code()].

Every code() value, in declaration order.

embedded_error_class(Err)

-spec embedded_error_class(term()) -> integer() | undefined.

The status to classify an embedded error object by: its HTTP status when it carries one, else the status its code / type name stands for (insufficient_quota → 429). undefined when it names nothing known.

embedded_error_status/1

-spec embedded_error_status(term()) -> 400..599 | undefined.

The HTTP status an error object delivered inside a 2xx body or a stream frame carries: OpenRouter's post-processing errors put the real status in error.code (e.g. 502, as a number or a three-digit string). Anything else is not a status.

empty_body(Status)

-spec empty_body(integer()) -> thinwrap_llm:connector_error().

A 2xx response with no decodable JSON body (a proxy or captive-portal HTML page, a truncated read). Without this guard the connector would parse nothing into an empty "successful" result.

fail(Error)

Abort the current operation with Error. Only valid inside a call made through thinwrap_llm, which turns it into {error, Error}.

invalid_request(Msg)

-spec invalid_request(binary()) -> thinwrap_llm:connector_error().

A pre-flight invalid_request (no HTTP round-trip).

malformed_body(Status, RawBody, Msg)

-spec malformed_body(integer(), term(), binary()) -> thinwrap_llm:connector_error().

A 2xx JSON body that decodes but cannot be a real result (one embedding per input missing, a vector cell that is not a number). Coercing it would hand the caller silently wrong data.

new(Code, Fields)

-spec new(code(), map()) -> thinwrap_llm:connector_error().

Build an error. Fields may carry status, provider_message, message and cause; message falls back to provider_message, then to a generic text, so it is always present. undefined values are dropped.

parse_retry_after(Value)

-spec parse_retry_after(binary()) -> non_neg_integer() | undefined.

parse_retry_after/2 against the current time.

parse_retry_after(Value, NowSecs)

-spec parse_retry_after(binary(), integer()) -> non_neg_integer() | undefined.

Seconds to wait per RFC 9110: delay-seconds is a non-negative integer, so 1.5 or -5 is ignored; an HTTP-date (IMF-fixdate, RFC 850 or asctime, matched strictly so free text such as tomorrow never reads as a date) gives the time until it, and a date already past means "retry now" (0). Anything else is undefined. NowSecs is Unix seconds.

stream_ended_early()

-spec stream_ended_early() -> thinwrap_llm:connector_error().

A stream whose body ended before the provider's terminal event. Every supported provider closes a complete stream with one, so an EOF before it is a truncated answer (dropped connection, proxy timeout), not a short one.

vendor_error(Status, Headers, RawBody, Code, ProviderMsg)

-spec vendor_error(integer(), thinwrap_llm_transport:headers(), term(), code(), binary() | undefined) ->
                      thinwrap_llm:connector_error().

The error for a non-2xx response (or an error object inside a 2xx body or a stream frame, which keeps the status it arrived with). The status-to-code classification and the message are the connector's; this adds the shared Retry-After surfacing.