Skip to main content

Crate apollo_errors

Crate apollo_errors 

Source
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;
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(),
};

// Render to different formats
let json = error.to_json().unwrap();
let graphql = error.to_graphql().unwrap();
let jsonrpc = error.to_jsonrpc().unwrap();
let html = error.to_html();
let text = error.to_text();

§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
  • -32000 to -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};

fn handle_error(error: Box<dyn std::error::Error + Send + Sync>) {
    let json = error.to_json().unwrap();
    println!("{}", json);
}

Re-exports§

pub use miette;
pub use http;

Structs§

ErrorFieldMetadata
Metadata for a field within an error variant
ErrorMetadata
An error type entry in the expanded catalog
ErrorVariantMetadata
A variant entry in the expanded catalog

Traits§

Error
The core trait for apollo errors.
ErrorExt
Extension trait for formatting any error type
HeapErrorExt
Extension trait for heap-allocated error types without ’static bounds

Functions§

error_catalog
Build an expanded error catalog

Derive Macros§

Error