Sumup.Error (Sumup v1.0.0)

Copy Markdown View Source

Normalized representation of every error the SumUp API can return.

The SumUp API surface grew organically and, as a result, exposes two different error shapes depending on which generation of the platform handles a given request:

  • Legacy resources (Checkouts, Customers, Transactions, Payouts) return {"error_code": "...", "message": "...", "param": "..."}, and for multi-field validation failures some of these same endpoints return a list of that same object instead of a single one.
  • Newer resources (Readers, Members, Memberships, Merchants) and the API gateway itself (every 401, regardless of resource) return RFC 9457 Problem Details: {"type": "...", "title": "...", "status": ..., "detail": "...", "instance": "..."} with content-type: application/problem+json.

Sumup.Error normalizes both shapes into a single struct so callers never need to know which generation of the API they're talking to. Nothing is lost: the raw, un-normalized body is always kept in :raw and the distinguishing shape in :source.

Summary

Functions

Builds a Sumup.Error for transport-level failures (timeouts, DNS, TLS, ...).

Builds a Sumup.Error from an HTTP response (status + decoded body).

Human readable summary of an error, suitable for logging.

Returns true if the error represents a client-safe-to-retry condition (429 or 5xx).

Types

source()

@type source() :: :problem | :legacy | :legacy_list | :transport | :unknown

t()

@type t() :: %Sumup.Error{
  code: String.t() | nil,
  errors: [t()],
  instance: String.t() | nil,
  message: String.t() | nil,
  param: String.t() | nil,
  raw: term(),
  request_id: String.t() | nil,
  source: source(),
  status: pos_integer() | nil,
  title: String.t() | nil,
  type: String.t() | nil
}

Functions

from_exception(exception)

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

Builds a Sumup.Error for transport-level failures (timeouts, DNS, TLS, ...).

from_response(status, body, response \\ nil)

@spec from_response(pos_integer(), term(), Req.Response.t() | nil) :: t()

Builds a Sumup.Error from an HTTP response (status + decoded body).

Dispatch order:

  1. If the body already looks like a Problem Details object (has a "title" or "type" key, or the response content-type is application/problem+json) it is decoded as :problem.
  2. If the body is a list of legacy error objects, it is decoded as :legacy_list, with each entry normalized into a child t/0 and exposed through :errors, and the struct itself carrying the first entry's fields for convenience.
  3. If the body is a single legacy error object, it is decoded as :legacy.
  4. Otherwise the raw body is preserved and :source is :unknown.

message(error)

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

Human readable summary of an error, suitable for logging.

retryable?(error)

@spec retryable?(t()) :: boolean()

Returns true if the error represents a client-safe-to-retry condition (429 or 5xx).