Lines
0 %
Functions
Branches
100 %
use axum::response::IntoResponse;
use http::StatusCode;
use sophia::{api::source::StreamError, iri::InvalidIri};
use std::{backtrace::Backtrace, error::Error, fmt::Display, path::PathBuf};
#[derive(Debug)]
pub(crate) enum MyError {
Tera(tera::Error),
NotFound(String),
Request(reqwest::Error),
InvalidIri(InvalidIri),
StreamError(Box<dyn std::error::Error>),
FormatError(Box<dyn std::error::Error>),
IoError(PathBuf, std::io::Error, Backtrace),
Error(Box<dyn Error>, Backtrace),
}
impl MyError {
pub(crate) fn format_error(error: impl Error + 'static) -> Self {
Self::FormatError(Box::new(error))
pub(crate) fn io_error(path: PathBuf, error: std::io::Error) -> Self {
Self::IoError(path, error, Backtrace::capture())
impl Display for MyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Tera(error) => error.fmt(f),
Self::NotFound(msg) => msg.fmt(f),
Self::IoError(path, e, _b) => write!(f, "{} {}", e, path.display()),
Self::Error(e, _b) => e.fmt(f),
_ => todo!(),
impl Error for MyError {}
impl From<tera::Error> for MyError {
fn from(value: tera::Error) -> Self {
Self::Tera(value)
impl From<reqwest::Error> for MyError {
fn from(value: reqwest::Error) -> Self {
Self::Request(value)
impl From<InvalidIri> for MyError {
fn from(value: InvalidIri) -> Self {
Self::InvalidIri(value)
impl<A: std::error::Error + 'static, B: std::error::Error + 'static> From<StreamError<A, B>>
for MyError
{
fn from(value: StreamError<A, B>) -> Self {
Self::StreamError(Box::new(value))
impl From<Box<dyn std::error::Error>> for MyError {
fn from(value: Box<dyn std::error::Error>) -> Self {
Self::Error(value, Backtrace::capture())
fn error_string(error: &dyn Error, backtrace: Option<Backtrace>) -> String {
let mut msg = format!("Something went wrong: {}", error);
if let Some(source) = error.source() {
msg += &error_string(source, None);
if let Some(backtrace) = backtrace {
msg += &format!("{}", backtrace);
msg
impl IntoResponse for MyError {
fn into_response(self) -> axum::response::Response {
Self::Tera(error) => (
StatusCode::INTERNAL_SERVER_ERROR,
error_string(&error, None),
)
.into_response(),
Self::NotFound(msg) => (StatusCode::NOT_FOUND, msg).into_response(),
Self::IoError(path, error, backtrace) => (
format!("{} {} {}", path.display(), error, backtrace),
Self::Error(error, backtrace) => (
error_string(error.as_ref(), Some(backtrace)),