TypeSafe.Error exception (TypeSafe AI v0.1.0-alpha.1)

Copy Markdown View Source

The single error value returned by every {:error, _} tuple in this library.

Errors are values, not exceptions, so callers can pattern match on type without rescuing. The bang variants (TypeSafe.evaluate!/4 and friends) raise this same struct, which is why it is also an exception.

Types

  • :auth - HTTP 401. The API key is missing or invalid.
  • :validation - HTTP 400 or 422 from the API (a malformed body, an unknown model, too many options), or a problem this library caught locally before sending anything (for example a Score with one level). status is nil for local validation errors.
  • :rate_limited - HTTP 429. Retried automatically; you only see it once the retry policy gives up.
  • :overloaded - HTTP 529 (and 503). Also retried automatically.
  • :timeout - the request exceeded its timeout without a response.
  • :connection - the request could not reach the server at all.
  • :unexpected - anything else: an unknown status, a body that failed to decode, or a response shape this library does not understand.

Fields

  • status - the HTTP status, or nil when no response was involved (local validation, timeouts, connection failures).

  • message - a one-line summary. For a 422 the API returns a list of %{"loc" => [...], "msg" => ...} entries; they are joined as body.questions.dept.criteria: Field required; ... so the offending field is readable without parsing body.

  • body - the decoded JSON error body, the raw string when it was not JSON, or nil. Log it for :unexpected errors: it shows what changed.

  • request_id - the x-typesafe-request-id response header. Quote it when contacting TypeSafe support.

  • retry_after_ms - the wait the server asked for, from retry-after-ms or Retry-After, kept even after retries are exhausted so you can back off before the next call or batch.

    case TypeSafe.evaluate(client, state, questions) do {:ok, result} -> result {:error, %TypeSafe.Error{type: :rate_limited, retry_after_ms: ms}} -> retry_later(ms) {:error, %TypeSafe.Error{request_id: id} = error} -> Logger.error(Exception.message(error), request_id: id) end

Summary

Functions

Maps a transport-level exception (no HTTP response) to an error.

Maps an HTTP response to an error. Only call this for non-2xx responses.

Builds an :unexpected error for a response we could not make sense of.

Builds a local validation error. Nothing was sent to the API.

Types

t()

@type t() :: %TypeSafe.Error{
  __exception__: true,
  body: term(),
  message: String.t(),
  request_id: String.t() | nil,
  retry_after_ms: non_neg_integer() | nil,
  status: pos_integer() | nil,
  type: type()
}

type()

@type type() ::
  :auth
  | :validation
  | :rate_limited
  | :overloaded
  | :timeout
  | :connection
  | :unexpected

Functions

from_exception(exception)

@spec from_exception(Exception.t()) :: t()

Maps a transport-level exception (no HTTP response) to an error.

from_response(response)

@spec from_response(Req.Response.t()) :: t()

Maps an HTTP response to an error. Only call this for non-2xx responses.

unexpected(message, body \\ nil)

@spec unexpected(String.t(), term()) :: t()

Builds an :unexpected error for a response we could not make sense of.

validation(message)

@spec validation(String.t()) :: t()

Builds a local validation error. Nothing was sent to the API.