Module catch_panic

Expand description

Convert panics into responses.

Note that using panics for error handling is not recommended. Prefer instead to use Result whenever possible.

§Example

use std::convert::Infallible;

use rama_http::{Request, Response, Body, header::HeaderName};
use rama_http::layer::catch_panic::CatchPanicLayer;
use rama_core::service::service_fn;
use rama_core::{Context, Service, Layer};
use rama_core::error::BoxError;

async fn handle(req: Request) -> Result<Response, Infallible> {
    panic!("something went wrong...")
}

let mut svc = (
    // Catch panics and convert them into responses.
    CatchPanicLayer::new(),
).into_layer(service_fn(handle));

// Call the service.
let request = Request::new(Body::default());

let response = svc.serve(Context::default(), request).await?;

assert_eq!(response.status(), 500);

Using a custom panic handler:

use std::{any::Any, convert::Infallible};

use rama_http::{Body, Request, StatusCode, Response, header::{self, HeaderName}};
use rama_http::layer::catch_panic::CatchPanicLayer;
use rama_core::service::{Service, service_fn};
use rama_core::Layer;
use rama_core::error::BoxError;

async fn handle(req: Request) -> Result<Response, Infallible> {
    panic!("something went wrong...")
}

fn handle_panic(err: Box<dyn Any + Send + 'static>) -> Response {
    let details = if let Some(s) = err.downcast_ref::<String>() {
        s.clone()
    } else if let Some(s) = err.downcast_ref::<&str>() {
        s.to_string()
    } else {
        "Unknown panic message".to_string()
    };

    let body = serde_json::json!({
        "error": {
            "kind": "panic",
            "details": details,
        }
    });
    let body = serde_json::to_string(&body).unwrap();

    Response::builder()
        .status(StatusCode::INTERNAL_SERVER_ERROR)
        .header(header::CONTENT_TYPE, "application/json")
        .body(Body::from(body))
        .unwrap()
}

let svc = (
    // Use `handle_panic` to create the response.
    CatchPanicLayer::custom(handle_panic),
).into_layer(service_fn(handle));

Structs§

CatchPanic
Middleware that catches panics and converts them into 500 Internal Server responses.
CatchPanicLayer
Layer that applies the CatchPanic middleware that catches panics and converts them into 500 Internal Server responses.
DefaultResponseForPanic
The default ResponseForPanic used by CatchPanic.

Traits§

ResponseForPanic
Trait for creating responses from panics.