Current section
Files
Jump to
Current section
Files
lib/power_of_three/query_error.ex
defmodule PowerOfThree.QueryError do
@moduledoc """
Unified error struct for query errors across different connection types (ADBC, HTTP).
Provides consistent error handling regardless of the underlying protocol.
"""
@enforce_keys [:message, :type]
defstruct [:message, :type, :details, :original_error]
@type error_type ::
:connection_error
| :query_error
| :timeout
| :auth_error
| :parse_error
| :translation_error
@type t :: %__MODULE__{
message: String.t(),
type: error_type(),
details: map(),
original_error: term()
}
@doc """
Creates a new QueryError.
## Examples
iex> PowerOfThree.QueryError.new("Connection failed", :connection_error)
%PowerOfThree.QueryError{message: "Connection failed", type: :connection_error, details: %{}}
iex> PowerOfThree.QueryError.new("Invalid query", :query_error, %{status: 400})
%PowerOfThree.QueryError{message: "Invalid query", type: :query_error, details: %{status: 400}}
"""
def new(message, type, details \\ %{}, original_error \\ nil) do
%__MODULE__{
message: message,
type: type,
details: details || %{},
original_error: original_error
}
end
@doc """
Creates a QueryError from an HTTP response status code.
Maps HTTP status codes to appropriate error types.
"""
def from_http_status(status, body \\ nil) do
case status do
400 ->
new("Invalid query", :query_error, %{status: 400, body: body})
401 ->
new("Authentication failed", :auth_error, %{status: 401})
403 ->
new("Access forbidden", :auth_error, %{status: 403})
404 ->
new("Resource not found", :connection_error, %{status: 404})
500 ->
new("Internal server error", :query_error, %{status: 500, body: body})
503 ->
new("Service unavailable", :connection_error, %{status: 503})
_ ->
new("HTTP error #{status}", :connection_error, %{status: status, body: body})
end
end
@doc """
Creates a QueryError from a timeout.
"""
def timeout(details \\ %{}) do
new("Request timeout", :timeout, details)
end
@doc """
Creates a QueryError from a connection failure.
"""
def connection_error(message, original_error \\ nil) do
new(message, :connection_error, %{}, original_error)
end
@doc """
Creates a QueryError from a parse error.
"""
def parse_error(message, original_error \\ nil) do
new(message, :parse_error, %{}, original_error)
end
@doc """
Creates a QueryError from a translation error (e.g., WHERE clause parsing).
"""
def translation_error(message) do
new(message, :translation_error, %{})
end
end
defimpl String.Chars, for: PowerOfThree.QueryError do
def to_string(%PowerOfThree.QueryError{message: message, type: type}) do
"[#{type}] #{message}"
end
end