diff --git a/examples/error-handling/Cargo.toml b/examples/error-handling/Cargo.toml new file mode 100644 index 00000000..f30538cd --- /dev/null +++ b/examples/error-handling/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum = { path = "../../axum" } +axum-extra = { path = "../../axum-extra" } +chrono = { version = "0.4", features = ["serde"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" +tokio = { version = "1.20", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/error-handling/src/main.rs b/examples/error-handling/src/main.rs new file mode 100644 index 00000000..45ee6cf8 --- /dev/null +++ b/examples/error-handling/src/main.rs @@ -0,0 +1,30 @@ +mod with_rejection; + +use std::net::SocketAddr; +use axum::{Server, Router, routing::get}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + + + +#[tokio::main] +async fn main() { + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::new( + std::env::var("RUST_LOG") + .unwrap_or_else(|_| "error_handling=debug".into()), + )) + .with(tracing_subscriber::fmt::layer()) + .init(); + + // Build our application with some routes + let app = Router::new() + .route("/withRejection", get(with_rejection::handler)); + + // Run our application + let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); + tracing::debug!("listening on {}", addr); + axum::Server::bind(&addr) + .serve(app.into_make_service()) + .await + .unwrap(); +} \ No newline at end of file diff --git a/examples/error-handling/src/with_rejection.rs b/examples/error-handling/src/with_rejection.rs new file mode 100644 index 00000000..6f61e051 --- /dev/null +++ b/examples/error-handling/src/with_rejection.rs @@ -0,0 +1,28 @@ +use axum::{extract::rejection::JsonRejection, response::IntoResponse, Json}; +use axum_extra::extract::WithRejection; +use chrono::Utc; +use serde_json::{json, Value}; +use thiserror::Error; + +pub async fn handler( + WithRejection(Json(value), _): WithRejection, ApiError>, +) -> impl IntoResponse { + dbg!(value); +} + +#[derive(Debug, Error)] +pub enum ApiError { + #[error(transparent)] + JsonExtractorRejection(#[from] JsonRejection), +} + +impl IntoResponse for ApiError { + fn into_response(self) -> axum::response::Response { + let payload = json!({ + "message": self.to_string(), + "timestamp": Utc::now(), + "origin": "with_rejection" + }); + Json(payload).into_response() + } +}