diff --git a/src/main.rs b/src/main.rs index 6481e017..6e889175 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::fs::Permissions; // not unix specific, just only for UNIX sockets stuff #[cfg(unix)] use std::os::unix::fs::PermissionsExt as _; /* not unix specific, just only for UNIX sockets stuff and *nix * container checks */ -use std::{io, net::SocketAddr, sync::atomic, time::Duration}; +use std::{any::Any, io, net::SocketAddr, sync::atomic, time::Duration}; use axum::{ extract::{DefaultBodyLimit, MatchedPath}, @@ -35,7 +35,7 @@ use tower_http::{ trace::{DefaultOnFailure, TraceLayer}, ServiceBuilderExt as _, }; -use tracing::{debug, error, info, warn, Level}; +use tracing::{debug, error, info, level_filters::LevelFilter, warn, Level}; use tracing_subscriber::{prelude::*, reload, EnvFilter, Registry}; mod routes; @@ -275,7 +275,6 @@ async fn build(server: &Server) -> io::Result io::Result Result<(), nix::errno::Errno> { Ok(()) } + +#[allow(clippy::needless_pass_by_value)] +fn catch_panic_layer(err: Box) -> http::Response> { + let details = if cfg!(debug_assertions) || LevelFilter::current() == LevelFilter::TRACE { + if let Some(s) = err.downcast_ref::() { + s.clone() + } else if let Some(s) = err.downcast_ref::<&str>() { + s.to_string() + } else { + "Unknown internal server error occurred.".to_owned() + } + } else { + "Internal server error occurred.".to_owned() + }; + + let body = if cfg!(debug_assertions) || LevelFilter::current() == LevelFilter::TRACE { + serde_json::json!({ + "errcode": "M_UNKNOWN", + "error": "M_UNKNOWN: Internal server error occurred", + "details": details, + }) + .to_string() + } else { + serde_json::json!({ + "errcode": "M_UNKNOWN", + "error": "M_UNKNOWN: Internal server error occurred", + }) + .to_string() + }; + + http::Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .header(header::CONTENT_TYPE, "application/json") + .body(http_body_util::Full::from(body)) + .expect("Failed to create response for our panic catcher?") +}