WhatsApp.Error exception (WhatsApp SDK v0.1.0)

Copy Markdown View Source

WhatsApp API error.

Represents both API errors (4xx/5xx responses with Meta error bodies) and connection-level errors (network failures, timeouts).

This module implements the Exception behaviour so errors can be raised when desired, but are typically returned in {:error, %WhatsApp.Error{}} tuples.

Meta Error Format

Meta's Graph API returns errors in a consistent format:

%{
  "error" => %{
    "message" => "Invalid OAuth access token...",
    "type" => "OAuthException",
    "code" => 190,
    "error_subcode" => 463,
    "fbtrace_id" => "AbC123dEf456",
    "is_transient" => false
  }
}

Usage

case WhatsApp.Messages.send(client, params) do
  {:ok, message} ->
    message

  {:error, %WhatsApp.Error{code: 190}} ->
    Logger.error("Invalid access token")

  {:error, %WhatsApp.Error{status: 429, retry_after: seconds}} ->
    Process.sleep(seconds * 1_000)

  {:error, %WhatsApp.Error{} = err} ->
    Logger.error("WhatsApp error #{err.code}: #{err.message}")
end

Summary

Functions

Build a connection-level error from a transport error or reason.

Build an error from an HTTP status code and a decoded response body.

Build an error from an HTTP status code, decoded response body, and response headers.

Returns the human-readable error message.

Returns whether the error is retryable.

Build an error for webhook verification failures.

Types

t()

@type t() :: %WhatsApp.Error{
  __exception__: true,
  code: integer() | nil,
  details: map() | nil,
  error_subcode: integer() | nil,
  error_type: String.t() | nil,
  fbtrace_id: String.t() | nil,
  is_transient: boolean(),
  message: String.t(),
  retry_after: integer() | nil,
  status: integer() | nil
}

Functions

connection_error(exception)

@spec connection_error(Exception.t() | String.t()) :: t()

Build a connection-level error from a transport error or reason.

Used for network failures, timeouts, and other connection issues where no HTTP response was received.

Examples

iex> error = WhatsApp.Error.connection_error(%Mint.TransportError{reason: :timeout})
iex> error.message
"timeout"

iex> error = WhatsApp.Error.connection_error("connection refused")
iex> error.message
"connection refused"

from_response(status, body)

@spec from_response(integer(), map()) :: t()

Build an error from an HTTP status code and a decoded response body.

Handles Meta's standard error format where the error details are nested under an "error" key, as well as responses that don't follow this format.

Examples

iex> body = %{"error" => %{"message" => "Invalid token", "type" => "OAuthException", "code" => 190}}
iex> error = WhatsApp.Error.from_response(401, body)
iex> error.code
190

from_response(status, body, headers)

@spec from_response(integer(), map(), list()) :: t()

Build an error from an HTTP status code, decoded response body, and response headers.

The headers list is inspected for a Retry-After header, which is parsed as an integer number of seconds.

Examples

iex> body = %{"error" => %{"message" => "Rate limited", "code" => 80007}}
iex> headers = [{"retry-after", "60"}]
iex> error = WhatsApp.Error.from_response(429, body, headers)
iex> error.retry_after
60

message(exception)

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

Returns the human-readable error message.

Examples

iex> WhatsApp.Error.message(%WhatsApp.Error{message: "Invalid token"})
"Invalid token"

retryable?(error)

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

Returns whether the error is retryable.

The following errors are considered retryable:

  • Rate limit errors (HTTP 429)
  • Server errors (HTTP 500, 502, 503)
  • Connection errors (no HTTP status code)
  • Errors explicitly marked as transient by Meta (is_transient: true)

Examples

iex> WhatsApp.Error.retryable?(%WhatsApp.Error{message: "rate limited", status: 429})
true

iex> WhatsApp.Error.retryable?(%WhatsApp.Error{message: "not found", status: 404})
false

webhook_verification_error(reason)

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

Build an error for webhook verification failures.

Examples

iex> error = WhatsApp.Error.webhook_verification_error("token mismatch")
iex> error.message
"Webhook verification failed: token mismatch"