1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
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<dyn std::any::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()
};
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::<SocketAddr>(),
)
.await
.context("serve")
}
|