Expand description
Structured error handling with multi-format output.
Define errors once and render them to JSON, GraphQL, HTML, or plain text.
§Quick Start
use apollo_errors::{Error, FormatConfig};
use miette::Diagnostic;
#[derive(Debug, Error, Diagnostic)]
pub enum AuthError {
#[error("Invalid credentials for user {username}")]
#[diagnostic(code(auth::invalid_credentials))]
InvalidCredentials {
#[extension]
username: String,
},
}
let error = AuthError::InvalidCredentials {
username: "alice".to_string(),
};
let config = FormatConfig::default();
// Render to different formats
let json = error.to_json(config).unwrap();
let graphql = error.to_graphql(config).unwrap();
let jsonrpc = error.to_jsonrpc(config).unwrap();
let html = error.to_html(config);
let text = error.to_text(config);§Defining Errors
Errors require three derives: Debug, Error, and Diagnostic.
#[derive(Debug, Error, Diagnostic)]
pub enum MyError {
#[error("Something went wrong")]
#[diagnostic(code(service::something_wrong))]
SomethingWrong,
}§Attributes
§Error Message
Use #[error("...")] to define the error message. Field interpolation is supported:
#[error("Failed to connect to {host}:{port}")]
ConnectionFailed { host: String, port: u16 },§Error Code
Use #[diagnostic(code(...))] to define a unique error code. Codes must have
at least two :: separated segments, all lowercase:
#[diagnostic(code(db::connection_failed))]
#[diagnostic(code(auth::invalid_token))]§Extension Fields
Mark fields with #[extension] to include them in JSON and GraphQL output:
InvalidPort {
#[extension]
port: u16,
#[extension]
config_file: String,
},§HTTP Status
Specify an HTTP status code (defaults to 500):
#[http_status(404)]
NotFound,§HTTP Headers
Mark fields to be returned as HTTP response headers. Supported types are u16, u32,
u64, i16, i32, i64, bool, and HeaderValue:
#[http_status(429)]
RateLimitExceeded {
#[http_header("Retry-After")]
retry_after: u64,
#[http_header("X-RateLimit-Remaining")]
remaining: u32,
},Header names are validated at compile time against RFC 7230. Headers are
automatically set when using [tower_http::ErrorLayer]. For Option<T> fields,
the header is only included when the value is Some.
§JSON-RPC Code
Specify a JSON-RPC 2.0 error code (defaults to -32000, “Server error”):
#[jsonrpc_code(-32602)]
InvalidParams { param: String },Reserved JSON-RPC codes:
-32700: Parse error-32600: Invalid Request-32601: Method not found-32602: Invalid params-32603: Internal error-32000to-32099: Server error (available for application use)
§Help Text and URLs
Provide additional context for users:
#[diagnostic(
code(config::invalid),
help("Check your configuration file"),
url("https://docs.example.com/errors/config-invalid")
)]§Error Chaining
Use #[source] to chain errors, or #[from] to also generate a From impl:
#[error("Database operation failed")]
#[diagnostic(code(db::operation_failed))]
DatabaseError {
#[from]
source: std::io::Error,
},§Dynamic Dispatch
Format any std::error::Error using the extension traits:
use apollo_errors::{ErrorExt, HeapErrorExt, FormatConfig};
fn handle_error(error: Box<dyn std::error::Error + Send + Sync>) {
let json = error.to_json(FormatConfig::default()).unwrap();
println!("{}", json);
}Re-exports§
Structs§
- Code
Metadata - All pre-computed case variants for an error code.
- Error
Field Metadata - Metadata for a field within an error variant
- Error
Metadata - An error type entry in the expanded catalog
- Error
Variant Metadata - A variant entry in the expanded catalog
- Format
Config - Configuration for error output formatting
Enums§
- Code
Case - Error code case for error codes in error output.
- Field
Case - Field name case for extension field names in error output.
Traits§
- Error
- The core trait for apollo errors.
- Error
Ext - Extension trait for formatting any error type
- Heap
Error Ext - Extension trait for heap-allocated error types without ’static bounds
Functions§
- error_
catalog - Build an expanded error catalog