awesome_operates/
error.rs

1use axum::{
2    http::StatusCode,
3    response::{IntoResponse, Response},
4    Json,
5};
6use snafu::prelude::*;
7use snafu::Location;
8
9#[derive(Debug, Snafu)]
10#[snafu(visibility(pub))]
11pub enum AppError {
12    #[snafu(display("Option value is None"))]
13    OptionNone { location: Location },
14
15    #[snafu(display("axum error: {}", source))]
16    Axum {
17        source: axum::Error,
18        location: Location,
19    },
20
21    #[snafu(display("proxy request error `{}`", source))]
22    RequestProxy {
23        location: Location,
24        source: reqwest::Error,
25    },
26
27    #[snafu(display("request build error `{}`", source))]
28    HttpRequestBuild {
29        location: Location,
30        source: http::Error,
31    },
32
33    #[snafu(display("request build from parts error `{}`", source))]
34    UriFromParts {
35        location: Location,
36        source: http::uri::InvalidUriParts,
37    },
38
39    #[snafu(display("request body error `{}`", source))]
40    RequestBodyRead {
41        location: Location,
42        source: reqwest::Error,
43    },
44
45    #[snafu(display("binary cannot be execute for filepath {}", filepath))]
46    BinaryCannotBeExecute {
47        location: Location,
48        filepath: String,
49    },
50
51    #[snafu(display("common io error {}", source))]
52    CommonIo {
53        location: Location,
54        source: std::io::Error,
55    },
56}
57
58impl IntoResponse for AppError {
59    fn into_response(self) -> Response {
60        let status_code = StatusCode::INTERNAL_SERVER_ERROR;
61        tracing::error!("error happened: {self:?}\n display error: {self}");
62        (
63            status_code,
64            Json(serde_json::json!({
65                "message": format!("{}", self)
66            })),
67        )
68            .into_response()
69    }
70}
71
72pub type Result<T> = std::result::Result<T, AppError>;