use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
#[derive(Debug)]
#[must_use]
pub struct ErrorResponse {
response: Response,
source: Option<anyhow::Error>,
}
impl ErrorResponse {
pub(crate) fn from_response(response: Response) -> Self {
Self { response, source: None }
}
pub(crate) fn from_status(status: StatusCode) -> Self {
Self { response: status.into_response(), source: None }
}
pub(crate) fn with_source(self, source: anyhow::Error) -> Self {
Self { response: self.response, source: Some(source) }
}
pub fn error(&self) -> Option<&anyhow::Error> {
self.source.as_ref()
}
}
impl<E> From<E> for ErrorResponse
where
E: Into<anyhow::Error>,
{
fn from(error: E) -> Self {
let error = error.into();
let response = StatusCode::INTERNAL_SERVER_ERROR.into_response();
Self { response, source: Some(error) }
}
}
impl IntoResponse for ErrorResponse {
fn into_response(self) -> Response {
if let Some(source) = self.source {
tracing::error!("response error: {source:?}");
}
self.response
}
}