Line data Source code
1 : //! Things stolen from `libs/utils/src/http` to add hyper 1.0 compatibility
2 : //! Will merge back in at some point in the future.
3 :
4 : use anyhow::Context;
5 : use bytes::Bytes;
6 : use http::{Response, StatusCode};
7 : use http_body_util::combinators::BoxBody;
8 : use http_body_util::{BodyExt, Full};
9 : use serde::Serialize;
10 : use utils::http::error::ApiError;
11 :
12 : /// Like [`ApiError::into_response`]
13 0 : pub(crate) fn api_error_into_response(this: ApiError) -> Response<BoxBody<Bytes, hyper::Error>> {
14 0 : match this {
15 0 : ApiError::BadRequest(err) => HttpErrorBody::response_from_msg_and_status(
16 0 : format!("{err:#?}"), // use debug printing so that we give the cause
17 0 : StatusCode::BAD_REQUEST,
18 0 : ),
19 : ApiError::Forbidden(_) => {
20 0 : HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::FORBIDDEN)
21 : }
22 : ApiError::Unauthorized(_) => {
23 0 : HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::UNAUTHORIZED)
24 : }
25 : ApiError::NotFound(_) => {
26 0 : HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::NOT_FOUND)
27 : }
28 : ApiError::Conflict(_) => {
29 0 : HttpErrorBody::response_from_msg_and_status(this.to_string(), StatusCode::CONFLICT)
30 : }
31 0 : ApiError::PreconditionFailed(_) => HttpErrorBody::response_from_msg_and_status(
32 0 : this.to_string(),
33 0 : StatusCode::PRECONDITION_FAILED,
34 0 : ),
35 0 : ApiError::ShuttingDown => HttpErrorBody::response_from_msg_and_status(
36 0 : "Shutting down".to_string(),
37 0 : StatusCode::SERVICE_UNAVAILABLE,
38 0 : ),
39 0 : ApiError::ResourceUnavailable(err) => HttpErrorBody::response_from_msg_and_status(
40 0 : err.to_string(),
41 0 : StatusCode::SERVICE_UNAVAILABLE,
42 0 : ),
43 0 : ApiError::TooManyRequests(err) => HttpErrorBody::response_from_msg_and_status(
44 0 : err.to_string(),
45 0 : StatusCode::TOO_MANY_REQUESTS,
46 0 : ),
47 0 : ApiError::Timeout(err) => HttpErrorBody::response_from_msg_and_status(
48 0 : err.to_string(),
49 0 : StatusCode::REQUEST_TIMEOUT,
50 0 : ),
51 0 : ApiError::Cancelled => HttpErrorBody::response_from_msg_and_status(
52 0 : this.to_string(),
53 0 : StatusCode::INTERNAL_SERVER_ERROR,
54 0 : ),
55 0 : ApiError::InternalServerError(err) => HttpErrorBody::response_from_msg_and_status(
56 0 : err.to_string(),
57 0 : StatusCode::INTERNAL_SERVER_ERROR,
58 0 : ),
59 : }
60 0 : }
61 :
62 : /// Same as [`utils::http::error::HttpErrorBody`]
63 : #[derive(Serialize)]
64 : struct HttpErrorBody {
65 : pub(crate) msg: String,
66 : }
67 :
68 : impl HttpErrorBody {
69 : /// Same as [`utils::http::error::HttpErrorBody::response_from_msg_and_status`]
70 0 : fn response_from_msg_and_status(
71 0 : msg: String,
72 0 : status: StatusCode,
73 0 : ) -> Response<BoxBody<Bytes, hyper::Error>> {
74 0 : HttpErrorBody { msg }.to_response(status)
75 0 : }
76 :
77 : /// Same as [`utils::http::error::HttpErrorBody::to_response`]
78 0 : fn to_response(&self, status: StatusCode) -> Response<BoxBody<Bytes, hyper::Error>> {
79 0 : Response::builder()
80 0 : .status(status)
81 0 : .header(http::header::CONTENT_TYPE, "application/json")
82 0 : // we do not have nested maps with non string keys so serialization shouldn't fail
83 0 : .body(
84 0 : Full::new(Bytes::from(serde_json::to_string(self).unwrap()))
85 0 : .map_err(|x| match x {})
86 0 : .boxed(),
87 0 : )
88 0 : .unwrap()
89 0 : }
90 : }
91 :
92 : /// Same as [`utils::http::json::json_response`]
93 0 : pub(crate) fn json_response<T: Serialize>(
94 0 : status: StatusCode,
95 0 : data: T,
96 0 : ) -> Result<Response<BoxBody<Bytes, hyper::Error>>, ApiError> {
97 0 : let json = serde_json::to_string(&data)
98 0 : .context("Failed to serialize JSON response")
99 0 : .map_err(ApiError::InternalServerError)?;
100 0 : let response = Response::builder()
101 0 : .status(status)
102 0 : .header(http::header::CONTENT_TYPE, "application/json")
103 0 : .body(Full::new(Bytes::from(json)).map_err(|x| match x {}).boxed())
104 0 : .map_err(|e| ApiError::InternalServerError(e.into()))?;
105 0 : Ok(response)
106 0 : }
|