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 Location(&'static Location<'static>),
100}