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}