linode_api_proxy/http_handlers/v4/
error.rs

1use axum::{
2    extract::Json,
3    http::{
4        header::{HeaderName, HeaderValue},
5        StatusCode,
6    },
7    response::{IntoResponse, Response},
8};
9use linode_api::{
10    endpoints::v4::ErrorResponseBody,
11    objects::v4::{Error, ErrorReason},
12};
13
14//
15#[derive(Debug)]
16pub enum HandleError {
17    RequestHeaderAuthorizationRequired,
18    RequestQueryMissing,
19    RequestQueryDeFailed(serde_qs::Error),
20    BackendRequestUriBuildFailed(axum::http::uri::InvalidUri),
21    BackendResponseStatusCodeMismatch(Response),
22    BackendResponseBodyReadFailed(axum::Error),
23    BackendResponseBodyDeFailed(serde_json::Error),
24    Other(
25        StatusCode,
26        ErrorReason,
27        Option<String>,
28        Option<Vec<(HeaderName, HeaderValue)>>,
29    ),
30}
31
32//
33impl IntoResponse for HandleError {
34    fn into_response(self) -> Response {
35        let (status_code, reason, field) = match self {
36            HandleError::RequestHeaderAuthorizationRequired => {
37                (StatusCode::UNAUTHORIZED, ErrorReason::InvalidToken, None)
38            }
39            HandleError::RequestQueryMissing => (
40                StatusCode::BAD_REQUEST,
41                ErrorReason::Other("request query required".into()),
42                None,
43            ),
44            HandleError::RequestQueryDeFailed(err) => (
45                StatusCode::BAD_REQUEST,
46                ErrorReason::Other(format!("request query de failed, err:{err}")),
47                None,
48            ),
49            HandleError::BackendRequestUriBuildFailed(err) => (
50                StatusCode::from_u16(599).expect("Never"),
51                ErrorReason::Other(format!("backend request uri build failed, err:{err}")),
52                None,
53            ),
54            HandleError::BackendResponseStatusCodeMismatch(resp) => return resp,
55            HandleError::BackendResponseBodyReadFailed(err) => (
56                StatusCode::from_u16(599).expect("Never"),
57                ErrorReason::Other(format!("backend response body read failed, err:{err}")),
58                None,
59            ),
60            HandleError::BackendResponseBodyDeFailed(err) => (
61                StatusCode::from_u16(599).expect("Never"),
62                ErrorReason::Other(format!("backend response body de failed, err:{err}")),
63                None,
64            ),
65            HandleError::Other(status_code, reason, field, backend_resp_headers) => {
66                let body = Json(ErrorResponseBody {
67                    errors: vec![Error { field, reason }],
68                });
69                let mut resp = (status_code, body).into_response();
70                if let Some(backend_resp_headers) = backend_resp_headers {
71                    for (k, v) in backend_resp_headers {
72                        resp.headers_mut().insert(k, v);
73                    }
74                }
75                return resp;
76            }
77        };
78
79        let body = Json(ErrorResponseBody {
80            errors: vec![Error { field, reason }],
81        });
82        (status_code, body).into_response()
83    }
84}