1
0
Fork 0
mirror of https://github.com/tokio-rs/axum.git synced 2025-04-26 13:56:22 +02:00

examples(error-handling): derive_from_request

This commit is contained in:
Altair-Bueno 2022-08-18 20:41:26 +02:00
parent e39433ea5f
commit edd4e7b661
3 changed files with 51 additions and 2 deletions
examples/error-handling

View file

@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
axum = { path = "../../axum", features=["matched-path"] }
axum-extra = { path = "../../axum-extra" }
axum-macros = { path = "../../axum-macros" }
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View file

@ -0,0 +1,46 @@
use axum::{extract::rejection::JsonRejection, http::StatusCode, response::IntoResponse};
use axum_macros::FromRequest;
use chrono::Utc;
use serde_json::{json, Value};
pub async fn handler(Json(value): Json<Value>) -> impl IntoResponse {
Json(dbg!(value));
}
// create an extractor that internally uses `axum::Json` but has a custom rejection
#[derive(FromRequest)]
#[from_request(via(axum::Json), rejection(ApiError))]
pub struct Json<T>(T);
#[derive(Debug)]
pub struct ApiError {
code: StatusCode,
message: String,
}
impl From<JsonRejection> for ApiError {
fn from(rejection: JsonRejection) -> Self {
let code = match rejection {
JsonRejection::JsonDataError(_) | JsonRejection::MissingJsonContentType(_) => {
StatusCode::BAD_REQUEST
}
_ => StatusCode::INTERNAL_SERVER_ERROR,
};
Self {
code,
message: rejection.to_string(),
}
}
}
impl IntoResponse for ApiError {
fn into_response(self) -> axum::response::Response {
let payload = json!({
"message": self.message,
"timestamp": Utc::now(),
"origin": "derive_from_request"
});
(self.code, axum::Json(payload)).into_response()
}
}

View file

@ -1,5 +1,6 @@
mod with_rejection;
mod custom_extractor;
mod derive_from_request;
mod with_rejection;
use axum::{routing::get, Router, Server};
use std::net::SocketAddr;
@ -17,7 +18,8 @@ async fn main() {
// Build our application with some routes
let app = Router::new()
.route("/withRejection", get(with_rejection::handler))
.route("/customExtractor", get(custom_extractor::handler));
.route("/customExtractor", get(custom_extractor::handler))
.route("/deriveFromRequest", get(derive_from_request::handler));
// Run our application
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));