use std::net::SocketAddr; use anyhow::{Context, Result}; use axum::{ http::StatusCode, response::{IntoResponse, Response}, routing::get, Router, }; use tower_http::{ catch_panic::CatchPanicLayer, trace::{self, TraceLayer}, }; use tracing::{error, info, Level}; use tracing_subscriber::FmtSubscriber; fn handle_panic(err: Box) -> Response { let details = if let Some(s) = err.downcast_ref::() { s.clone() } else if let Some(s) = err.downcast_ref::<&str>() { s.to_string() } else { "Unknown panic message".to_string() }; error!(details = details, "Handler paniced"); (StatusCode::INTERNAL_SERVER_ERROR).into_response() } #[tokio::main] async fn main() -> Result<()> { let subscriber = FmtSubscriber::builder() .with_max_level(Level::TRACE) .finish(); tracing::subscriber::set_global_default(subscriber) .expect("set global default subscriber failed"); let app = Router::new() .route("/", get(|| async { "wat" })) .layer(CatchPanicLayer::custom(handle_panic)) .layer( TraceLayer::new_for_http() .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) .on_response(trace::DefaultOnResponse::new().level(Level::INFO)), ); let addr = "0.0.0.0:4800"; info!("Listening on {addr}"); let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); axum::serve( listener, app.into_make_service_with_connect_info::(), ) .await .context("serve") }