1use axum::{
2 http::StatusCode,
3 response::{IntoResponse, Response},
4};
5use tracing::error;
6
7#[derive(Debug)]
8pub enum Err {
9 Any(anyhow::Error),
10 Response(Response),
11}
12
13#[derive(Debug)]
14pub struct Error(pub Err);
15
16pub type Result<T, E = Error> = anyhow::Result<T, E>;
17
18impl IntoResponse for Error {
19 fn into_response(self) -> Response {
20 let err = self.0;
21 match err {
22 Err::Any(err) => {
23 error!("{}\n{}", err.backtrace(), err);
24 (StatusCode::INTERNAL_SERVER_ERROR, format!("ERR: {}", err)).into_response()
25 }
26 Err::Response(r) => r,
27 }
28 }
29}
30
31impl<E> From<E> for Error
32where
33 E: Into<anyhow::Error>,
34{
35 fn from(err: E) -> Self {
36 Self(Err::Any(err.into()))
37 }
38}
39
40pub fn err<T>(code: StatusCode, body: impl IntoResponse) -> Result<T, Error> {
41 let mut res = body.into_response();
42 *res.status_mut() = code;
43 std::result::Result::Err(Error(Err::Response(res)))?
44}