shiny_common/
error.rs

1use std::borrow::Cow;
2use std::error::Error;
3use std::fmt::{Debug, Display, Formatter};
4use std::panic::Location;
5use crate::pointer_utils::ToBox;
6
7#[derive(Debug)]
8pub struct ServiceError {
9    trace: ErrorTrace,
10    kind: ServiceErrorKind,
11    source: Option<Box<dyn Error + Send>>,
12}
13
14impl Display for ServiceError {
15    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
16        match &self.kind {
17            ServiceErrorKind::InternalError { code } => {
18                write!(f, "internal error [error_code = `{code}`]")?;
19            }
20            ServiceErrorKind::DependencyError { dependency_name, code, } => {
21                write!(f, "dependency error [dependency_name = `{dependency_name}`] [error_code = `{code}`]")?;
22            }
23        };
24
25        Ok(())
26    }
27}
28
29impl Error for ServiceError {
30    fn source(&self) -> Option<&(dyn Error + 'static)> {
31        match &self.source {
32            None => { None }
33            Some(err) => { Some(&**err) }
34        }
35    }
36}
37
38impl ServiceError {
39    pub fn internal_error(
40        code: Cow<'static, str>,
41        source: Option<Box<dyn Error + Send>>,
42        trace: ErrorTrace,
43    ) -> ServiceError {
44        ServiceError {
45            trace,
46            source,
47            kind: ServiceErrorKind::InternalError { code },
48        }
49    }
50
51    pub fn dependency_error(
52        dependency_name: Cow<'static, str>,
53        code: Cow<'static, str>,
54        source: Option<Box<dyn Error + Send>>,
55        trace: ErrorTrace,
56    ) -> ServiceError {
57        ServiceError {
58            trace,
59            source,
60            kind: ServiceErrorKind::DependencyError {
61                code,
62                dependency_name,
63            },
64        }
65    }
66
67    pub fn set_error<T>(&mut self, error: T)
68        where T: Error + Send + 'static
69    {
70        self.source = Some(error.boxed())
71    }
72
73    pub fn with_error<T>(mut self, error: T) -> ServiceError
74        where T: Error + Send + 'static
75    {
76        self.set_error(error);
77        self
78    }
79
80    pub fn trace(&self) -> &ErrorTrace {
81        &self.trace
82    }
83}
84
85#[derive(Debug)]
86enum ServiceErrorKind {
87    InternalError {
88        code: Cow<'static, str>,
89    },
90    DependencyError {
91        code: Cow<'static, str>,
92        dependency_name: Cow<'static, str>,
93    },
94}
95
96#[derive(Debug)]
97pub enum ErrorTrace {
98    // Backtrace(Backtrace),
99    Location(&'static Location<'static>),
100}