Skip to content

Instantly share code, notes, and snippets.

@manstie
Last active February 9, 2024 04:02
Show Gist options
  • Save manstie/ef93450a0d8521589be7ce59e70e266c to your computer and use it in GitHub Desktop.
Save manstie/ef93450a0d8521589be7ce59e70e266c to your computer and use it in GitHub Desktop.
Generic Axum Error Handler
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
};
use std::{fmt, panic::Location};
// Make our own error that wraps all errors
pub struct AppError {
inner: Box<dyn std::error::Error>,
location: &'static Location<'static>,
}
impl fmt::Display for AppError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "AppError at {}: {}", self.location, self.inner)
}
}
impl fmt::Debug for AppError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self)
}
}
// Tell axum how to convert `AppError` into a response.
impl IntoResponse for AppError {
fn into_response(self) -> Response {
log::error!("{}", self);
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Something went wrong: {}", self.inner),
)
.into_response()
}
}
// This enables using `?` on functions that return `Result<_, Error>` to turn them into
// `Result<_, AppError>`. That way you don't need to do that manually.
impl<E> From<E> for AppError
where
E: Into<Box<dyn std::error::Error>>,
{
#[track_caller]
fn from(err: E) -> Self {
Self {
inner: err.into(),
location: Location::caller(),
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment