LemonAi. Error
(lemon_ai v0.1.0)
View Source
Error handling utilities for AI provider responses.
This module provides functions for:
- Parsing HTTP error responses from various providers
- Extracting rate limit information from response headers
- Classifying errors for appropriate handling
- Generating user-friendly error messages
Summary
Functions
Check if the error represents an authentication failure.
Check if the error represents a context length exceeded error.
Extract rate limit information from response headers.
Generate a user-friendly error message from an error term.
Format rate limit information for display.
Parse an HTTP error response into a structured error.
Check if the error represents a rate limit error.
Check if an error is retryable.
Suggest a retry delay based on the error.
Suggest a retry delay based on parsed error with rate limit info.
Types
@type error_category() ::
:rate_limit
| :auth
| :client
| :context_length
| :server
| :transient
| :unknown
@type parsed_error() :: %{ category: error_category(), status: non_neg_integer() | nil, message: String.t(), provider_message: String.t() | nil, rate_limit_info: rate_limit_info() | nil, retryable: boolean() }
@type rate_limit_info() :: %{ limit: non_neg_integer() | nil, remaining: non_neg_integer() | nil, reset_at: DateTime.t() | nil, retry_after: non_neg_integer() | nil }
Functions
Check if the error represents an authentication failure.
Examples
iex> LemonAi.Error.auth_error?({:http_error, 401, "Unauthorized"})
true
iex> LemonAi.Error.auth_error?({:http_error, 500, "Server Error"})
false
Check if the error represents a context length exceeded error.
Examples
iex> LemonAi.Error.context_length_error?({:http_error, 400, %{"error" => %{"code" => "context_length_exceeded"}}})
true
iex> LemonAi.Error.context_length_error?({:http_error, 429, "Rate limited"})
false
@spec extract_rate_limit_info(map() | [{term(), term()}]) :: rate_limit_info()
Extract rate limit information from response headers.
Handles common rate limit header formats from OpenAI, Anthropic, and other providers.
Headers checked
x-ratelimit-limit-requests,x-ratelimit-limit-tokens- Total limitx-ratelimit-remaining-requests,x-ratelimit-remaining-tokens- Remainingx-ratelimit-reset-requests,x-ratelimit-reset-tokens- Reset timestampretry-after- Seconds until retry is allowedretry-after-ms,x-ms-retry-after-ms- Milliseconds until retry is allowed
Generate a user-friendly error message from an error term.
@spec format_rate_limit_info(rate_limit_info() | nil) :: String.t()
Format rate limit information for display.
Examples
iex> info = %{limit: 100, remaining: 50, reset_at: DateTime.utc_now()}
iex> LemonAi.Error.format_rate_limit_info(info)
"Rate limit: 50/100 remaining"
@spec parse_http_error(non_neg_integer(), term(), map() | [{term(), term()}]) :: parsed_error()
Parse an HTTP error response into a structured error.
Examples
iex> LemonAi.Error.parse_http_error(429, %{"error" => %{"message" => "Rate limit exceeded"}}, headers)
%{category: :rate_limit, status: 429, message: "Rate limit exceeded", ...}
iex> LemonAi.Error.parse_http_error(500, "Internal Server Error", [])
%{category: :server, status: 500, message: "Internal server error", ...}
Check if the error represents a rate limit error.
Examples
iex> LemonAi.Error.rate_limit_error?({:http_error, 429, "Rate limited"})
true
iex> LemonAi.Error.rate_limit_error?(:rate_limited)
true
iex> LemonAi.Error.rate_limit_error?({:http_error, 500, "Server Error"})
false
Check if an error is retryable.
@spec suggested_retry_delay(term()) :: non_neg_integer() | nil
Suggest a retry delay based on the error.
Returns the suggested delay in milliseconds, or nil if not applicable. Uses rate limit headers if available for more accurate retry timing.
@spec suggested_retry_delay_from_error(parsed_error()) :: non_neg_integer() | nil
Suggest a retry delay based on parsed error with rate limit info.
This version considers rate limit headers for more accurate retry timing.
Examples
iex> error = %{rate_limit_info: %{retry_after: 30_000}}
iex> LemonAi.Error.suggested_retry_delay_from_error(error)
30_000
iex> error = %{status: 503, rate_limit_info: nil}
iex> LemonAi.Error.suggested_retry_delay_from_error(error)
5_000