From 3533d96215ec14db41eb2d4cdd3314c5d10f4f6e Mon Sep 17 00:00:00 2001
From: Altair-Bueno <67512202+Altair-Bueno@users.noreply.github.com>
Date: Thu, 18 Aug 2022 20:53:34 +0200
Subject: [PATCH] examples(error-handling): Using `thiserror` for
 `derive_from_request`

---
 .../error-handling/src/derive_from_request.rs | 39 ++++++++-----------
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/examples/error-handling/src/derive_from_request.rs b/examples/error-handling/src/derive_from_request.rs
index 5d6da96d..ab3422c1 100644
--- a/examples/error-handling/src/derive_from_request.rs
+++ b/examples/error-handling/src/derive_from_request.rs
@@ -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()
     }
 }