poem_ext/
panic_handler.rs

1//! Contains a middlware that automatically responds with an internal server
2//! error whenever the current thread is panicking.
3//!
4//! #### Example
5//! ```
6//! use poem::{middleware::CatchPanic, EndpointExt, Route};
7//! use poem_ext::panic_handler::PanicHandler;
8//! use poem_openapi::{payload::PlainText, OpenApi, OpenApiService};
9//!
10//! struct Api;
11//!
12//! #[OpenApi]
13//! impl Api {
14//!     #[oai(path = "/test", method = "get")]
15//!     async fn test(&self) -> PlainText<&'static str> {
16//!         // status = 500, content = {"error":"internal_server_error"}
17//!         panic!("at the disco")
18//!     }
19//! }
20//!
21//! let api_service = OpenApiService::new(Api, "Test", "0.1.0");
22//! let app = Route::new()
23//!     .nest("/", api_service)
24//!     .with(PanicHandler::middleware());
25//! ```
26
27use poem::middleware::CatchPanic;
28
29use crate::responses::{make_internal_server_error, ErrorResponse};
30
31/// Custom panic handler.
32#[derive(Debug, Clone)]
33pub struct PanicHandler;
34
35impl PanicHandler {
36    /// Creates a [`CatchPanic`] middlware that uses this panic handler.
37    pub fn middleware() -> CatchPanic<Self> {
38        CatchPanic::new().with_handler(Self)
39    }
40}
41
42impl poem::middleware::PanicHandler for PanicHandler {
43    type Response = ErrorResponse;
44
45    fn get_response(&self, _err: Box<dyn std::any::Any + Send + 'static>) -> Self::Response {
46        make_internal_server_error()
47    }
48}