1
0
Fork 0
mirror of https://github.com/tokio-rs/axum.git synced 2025-03-26 00:27:01 +01:00

examples(error-handling): Using thiserror for derive_from_request

This commit is contained in:
Altair-Bueno 2022-08-18 20:53:34 +02:00
parent 16ea19d195
commit 3533d96215

View file

@ -2,6 +2,7 @@ use axum::{extract::rejection::JsonRejection, http::StatusCode, response::IntoRe
use axum_macros::FromRequest;
use chrono::Utc;
use serde_json::{json, Value};
use thiserror::Error;
pub async fn handler(Json(value): Json<Value>) -> impl IntoResponse {
Json(dbg!(value));
@ -12,35 +13,27 @@ pub async fn handler(Json(value): Json<Value>) -> impl IntoResponse {
#[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(),
}
}
#[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.message,
"message": self.to_string(),
"timestamp": Utc::now(),
"origin": "derive_from_request"
"origin": "with_rejection"
});
(self.code, axum::Json(payload)).into_response()
let code = match self {
ApiError::JsonExtractorRejection(x) => match x {
JsonRejection::JsonDataError(_) | JsonRejection::MissingJsonContentType(_) => {
StatusCode::BAD_REQUEST
}
_ => StatusCode::INTERNAL_SERVER_ERROR,
},
};
(code, axum::Json(payload)).into_response()
}
}