Skip to main content

ntex_error/
info.rs

1use std::{any::Any, any::TypeId, error, fmt, sync::Arc};
2
3use crate::{Backtrace, Error, ErrorDiagnostic, ResultType, repr::ErrorRepr};
4
5trait ErrorInformation: fmt::Display + fmt::Debug + 'static {
6    fn typ(&self) -> ResultType;
7
8    fn tag(&self) -> Option<&crate::Bytes>;
9
10    fn service(&self) -> Option<&'static str>;
11
12    fn signature(&self) -> &'static str;
13
14    fn backtrace(&self) -> Option<&Backtrace>;
15
16    fn source(&self) -> Option<&(dyn error::Error + 'static)>;
17
18    fn get_item(&self, id: &TypeId) -> Option<&(dyn Any + Send + Sync)>;
19}
20
21impl<E> ErrorInformation for ErrorRepr<E>
22where
23    E: ErrorDiagnostic + error::Error,
24{
25    fn typ(&self) -> ResultType {
26        self.error.typ()
27    }
28
29    fn tag(&self) -> Option<&crate::Bytes> {
30        ErrorDiagnostic::tag(self)
31    }
32
33    fn service(&self) -> Option<&'static str> {
34        ErrorDiagnostic::service(self)
35    }
36
37    fn signature(&self) -> &'static str {
38        self.error.signature()
39    }
40
41    fn backtrace(&self) -> Option<&Backtrace> {
42        ErrorDiagnostic::backtrace(self)
43    }
44
45    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
46        self.error.source()
47    }
48
49    fn get_item(&self, id: &TypeId) -> Option<&(dyn Any + Send + Sync)> {
50        self.ext.map.get(id).map(AsRef::as_ref)
51    }
52}
53
54/// Type-erased container holding error information.
55///
56/// This allows storing and passing error metadata without exposing the concrete type.
57#[derive(Clone)]
58pub struct ErrorInfo {
59    inner: Arc<dyn ErrorInformation>,
60}
61
62impl ErrorInfo {
63    /// Returns the classification of the result (e.g. success, client error, service error).
64    pub fn typ(&self) -> ResultType {
65        self.inner.typ()
66    }
67
68    /// Returns an optional tag associated with this error.
69    pub fn tag(&self) -> Option<&crate::Bytes> {
70        self.inner.tag()
71    }
72
73    /// Returns the name of the responsible service, if applicable.
74    pub fn service(&self) -> Option<&'static str> {
75        self.inner.service()
76    }
77
78    /// Returns a stable identifier for the specific error classification.
79    pub fn signature(&self) -> &'static str {
80        self.inner.signature()
81    }
82
83    /// Returns a backtrace for debugging purposes, if available.
84    pub fn backtrace(&self) -> Option<&Backtrace> {
85        self.inner.backtrace()
86    }
87
88    /// Returns a reference to a previously stored value of type `T` from this error.
89    pub fn get_item<T: 'static>(&self) -> Option<&T> {
90        self.inner
91            .get_item(&TypeId::of::<T>())
92            .and_then(|boxed| boxed.downcast_ref())
93    }
94}
95
96impl<E> From<Error<E>> for ErrorInfo
97where
98    E: ErrorDiagnostic + error::Error,
99{
100    fn from(err: Error<E>) -> Self {
101        Self { inner: err.inner }
102    }
103}
104
105impl<E> From<&Error<E>> for ErrorInfo
106where
107    E: ErrorDiagnostic + error::Error,
108{
109    fn from(err: &Error<E>) -> Self {
110        Self {
111            inner: err.inner.clone(),
112        }
113    }
114}
115
116impl error::Error for ErrorInfo {
117    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
118        self.inner.source()
119    }
120}
121
122impl fmt::Debug for ErrorInfo {
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        fmt::Debug::fmt(&self.inner, f)
125    }
126}
127
128impl fmt::Display for ErrorInfo {
129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130        fmt::Display::fmt(&self.inner, f)
131    }
132}
133
134impl ErrorDiagnostic for ErrorInfo {
135    fn typ(&self) -> ResultType {
136        self.inner.typ()
137    }
138
139    fn signature(&self) -> &'static str {
140        self.inner.signature()
141    }
142
143    fn service(&self) -> Option<&'static str> {
144        self.inner.service()
145    }
146
147    fn backtrace(&self) -> Option<&Backtrace> {
148        self.inner.backtrace()
149    }
150}