Packages
snakepit
0.12.0
0.13.0
0.12.0
0.11.1
0.11.0
0.10.1
0.10.0
0.9.1
0.9.0
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
High-performance pooler and session manager for external language integrations. Supports Python, Node.js, Ruby, and more with gRPC streaming, session management, and production-ready process cleanup.
Current section
Files
Jump to
Current section
Files
lib/snakepit/error.ex
defmodule Snakepit.Error do
@moduledoc """
Structured error type for Snakepit operations.
Provides detailed context for debugging cross-language and distributed system issues.
Python exceptions translated from the gRPC bridge are returned as
`Snakepit.Error.*` exception structs (see `Snakepit.Error.PythonException`).
`Snakepit.Error` remains the structured error type for Snakepit runtime failures.
## Error Categories
- `:worker` - Worker process errors (not found, crashed, etc.)
- `:timeout` - Operation timed out
- `:python_error` - Exception from Python code
- `:grpc_error` - gRPC communication error
- `:validation` - Input validation error
- `:pool` - Pool management error
## Examples
# Create a worker error
error = Snakepit.Error.worker_error("Worker not found", %{worker_id: "w1"})
# Create a Python exception error
error = Snakepit.Error.python_error(
"ValueError",
"Invalid input",
traceback_string,
%{function: "process_data"}
)
# Pattern match in your code
case Snakepit.execute("command", %{}) do
{:ok, result} -> result
{:error, %Snakepit.Error{category: :timeout}} -> retry()
{:error, %Snakepit.Error{category: :python_error} = error} ->
Snakepit.Logger.error("Python error: \#{error.message}")
Snakepit.Logger.debug("Traceback: \#{error.python_traceback}")
{:error, error} -> {:error, error}
end
"""
@type category :: :worker | :timeout | :python_error | :grpc_error | :validation | :pool
@type t :: %__MODULE__{
category: category(),
message: String.t(),
details: map(),
python_traceback: String.t() | nil,
grpc_status: atom() | nil
}
defstruct [:category, :message, :details, :python_traceback, :grpc_status]
@doc """
Creates a worker-related error.
## Examples
iex> Snakepit.Error.worker_error("Worker crashed")
%Snakepit.Error{category: :worker, message: "Worker crashed", details: %{}}
iex> Snakepit.Error.worker_error("Worker not found", %{worker_id: "w1"})
%Snakepit.Error{category: :worker, message: "Worker not found", details: %{worker_id: "w1"}}
"""
@spec worker_error(String.t(), map()) :: t()
def worker_error(message, details \\ %{}) do
%__MODULE__{
category: :worker,
message: message,
details: details
}
end
@doc """
Creates a timeout error.
## Examples
iex> Snakepit.Error.timeout_error("Request timed out", %{timeout_ms: 5000})
%Snakepit.Error{category: :timeout, message: "Request timed out", details: %{timeout_ms: 5000}}
"""
@spec timeout_error(String.t(), map()) :: t()
def timeout_error(message, details \\ %{}) do
%__MODULE__{
category: :timeout,
message: message,
details: details
}
end
@doc """
Creates a Python exception error with traceback.
## Examples
iex> Snakepit.Error.python_error("ValueError", "Invalid input", "Traceback...")
%Snakepit.Error{
category: :python_error,
message: "ValueError: Invalid input",
python_traceback: "Traceback...",
details: %{exception_type: "ValueError"}
}
"""
@spec python_error(String.t(), String.t(), String.t(), map()) :: t()
def python_error(exception_type, message, traceback, details \\ %{}) do
%__MODULE__{
category: :python_error,
message: "#{exception_type}: #{message}",
details: Map.put(details, :exception_type, exception_type),
python_traceback: traceback
}
end
@doc """
Creates a gRPC communication error.
## Examples
iex> Snakepit.Error.grpc_error(:unavailable, "Service unavailable")
%Snakepit.Error{
category: :grpc_error,
message: "Service unavailable",
grpc_status: :unavailable
}
"""
@spec grpc_error(atom(), String.t(), map()) :: t()
def grpc_error(status, message, details \\ %{}) do
%__MODULE__{
category: :grpc_error,
message: message,
grpc_status: status,
details: details
}
end
@doc """
Creates a pool management error.
## Examples
iex> Snakepit.Error.pool_error("Pool not found", %{pool_name: :test})
%Snakepit.Error{category: :pool, message: "Pool not found", details: %{pool_name: :test}}
"""
@spec pool_error(String.t(), map()) :: t()
def pool_error(message, details \\ %{}) do
%__MODULE__{
category: :pool,
message: message,
details: details
}
end
@doc """
Creates a validation error.
## Examples
iex> Snakepit.Error.validation_error("Invalid field", %{field: "user_id"})
%Snakepit.Error{category: :validation, message: "Invalid field", details: %{field: "user_id"}}
"""
@spec validation_error(String.t(), map()) :: t()
def validation_error(message, details \\ %{}) do
%__MODULE__{
category: :validation,
message: message,
details: details
}
end
defimpl String.Chars do
def to_string(%Snakepit.Error{} = error) do
base = "[#{error.category}] #{error.message}"
details_str =
if map_size(error.details) > 0 do
"\nDetails: #{inspect(error.details)}"
else
""
end
traceback_str =
if error.python_traceback do
"\n\nPython Traceback:\n#{error.python_traceback}"
else
""
end
grpc_str =
if error.grpc_status do
"\ngRPC Status: #{error.grpc_status}"
else
""
end
base <> details_str <> grpc_str <> traceback_str
end
end
end