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
Functions
@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"
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
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
Returns the human-readable error message.
Examples
iex> WhatsApp.Error.message(%WhatsApp.Error{message: "Invalid token"})
"Invalid token"
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
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"