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:
parent
e39433ea5f
commit
edd4e7b661
3 changed files with 51 additions and 2 deletions
examples/error-handling
|
@ -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"
|
||||
|
|
46
examples/error-handling/src/derive_from_request.rs
Normal file
46
examples/error-handling/src/derive_from_request.rs
Normal 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()
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Reference in a new issue