rocketjson_data/error/
error_handling.rs1use crate::error::{self, JsonBodyError};
5
6pub fn get_catcher() -> rocket::Catcher {
17 rocket::Catcher::new(None, request_catcher)
18}
19
20#[derive(serde::Serialize)]
21struct DefaultError {
22 error: String
23}
24
25impl DefaultError {
26 fn new(error: String) -> Self {
27 Self {
28 error
29 }
30 }
31}
32
33fn request_catcher<'r>(status: rocket::http::Status, req: &'r rocket::Request<'_>) -> rocket::catcher::BoxFuture<'r> {
34 use rocket::response::Responder;
35
36 loop {
37 let local_cache = req.local_cache(move || JsonBodyError::NoError);
38
39 match local_cache {
40 JsonBodyError::NoError => break,
41 JsonBodyError::ValidationError(validation_errors) => {
42 let err = rocket::serde::json::Json::from(validation_errors.clone());
43 return Box::pin(async move {
44 rocket::response::Response::build_from(err.respond_to(req).unwrap())
45 .status(rocket::http::Status::BadRequest)
46 .header(rocket::http::ContentType::JSON)
47 .ok()
48 });
49 },
50 JsonBodyError::JsonValidationError => {
51 let err = rocket::serde::json::Json::from(DefaultError::new(String::from("Parsing JSON failed")));
52
53 return Box::pin(async move {
54 rocket::response::Response::build_from(err.respond_to(req).unwrap())
55 .status(status)
56 .header(rocket::http::ContentType::JSON)
57 .ok()
58 })
59 },
60 JsonBodyError::CustomError(message) => {
61 let err = rocket::serde::json::Json::from(DefaultError::new(message.clone()));
62
63 return Box::pin(async move {
64 rocket::response::Response::build_from(err.respond_to(req).unwrap())
65 .status(status)
66 .header(rocket::http::ContentType::JSON)
67 .ok()
68 })
69 }
70 }
71 }
72
73 let message = if status.reason().is_some() {
74 String::from(status.reason().unwrap())
75 } else {
76 format!("Unknown error: {}", status.code)
77 };
78
79 let err = rocket::serde::json::Json::from(DefaultError::new(message));
80
81 return Box::pin(async move {
82 rocket::response::Response::build_from(err.respond_to(req).unwrap())
83 .status(status)
84 .header(rocket::http::ContentType::JSON)
85 .ok()
86 })
87}
88
89impl<'r> rocket::response::Responder<'r, 'static> for error::ApiErrors {
90 fn respond_to(self, req: &'r rocket::request::Request<'_>) -> rocket::response::Result<'static> {
91 match self {
92 error::ApiErrors::ApiError(err) => {
93 let json = rocket::serde::json::Json::from(DefaultError::new(err.error));
94
95 rocket::response::Response::build_from(json.respond_to(req).unwrap())
96 .status(err.status)
97 .header(rocket::http::ContentType::JSON)
98 .ok()
99 },
100 error::ApiErrors::AnyError(_) => {
101 let json = rocket::serde::json::Json::from(DefaultError::new(String::from("Internal server error")));
102
103 rocket::response::Response::build_from(json.respond_to(req).unwrap())
104 .status(rocket::http::Status::InternalServerError)
105 .header(rocket::http::ContentType::JSON)
106 .ok()
107 }
108 }
109 }
110}