linode_api_proxy/http_handlers/v4/
error.rs1use 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#[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
32impl 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}