1pub use tracing_support::{debug, error, info, trace, warn, Level};
7
8#[cfg(feature = "testing")]
9pub use tracing_support::{init_for_tests, init_for_tests_with_level};
10
11mod macros;
12
13#[cfg(feature = "backtrace")]
14pub use backtrace;
17
18#[cfg(not(feature = "backtrace"))]
19pub mod backtrace {
21 use std::fmt;
22
23 pub struct Backtrace;
24
25 impl Backtrace {
26 pub fn new() -> Self {
27 Backtrace
28 }
29 }
30
31 impl Default for Backtrace {
32 fn default() -> Self {
33 Self::new()
34 }
35 }
36
37 impl fmt::Debug for Backtrace {
38 #[cold]
39 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40 write!(f, "Not available")
41 }
42 }
43}
44
45mod redact;
46pub use redact::*;
47
48mod error_tracing;
49pub use error_tracing::{report_breadcrumb, report_error_to_app};
50
51pub use error_support_macros::handle_error;
52
53mod handling;
54pub use handling::{convert_log_report_error, ErrorHandling, ErrorReporting, GetErrorHandling};
55
56#[macro_export]
62macro_rules! define_error_wrapper {
63 ($Kind:ty) => {
64 pub type Result<T, E = Error> = std::result::Result<T, E>;
65 struct ErrorData {
66 kind: $Kind,
67 backtrace: Option<std::sync::Mutex<$crate::backtrace::Backtrace>>,
68 }
69
70 impl ErrorData {
71 #[cold]
72 fn new(kind: $Kind) -> Self {
73 ErrorData {
74 kind,
75 #[cfg(feature = "backtrace")]
76 backtrace: Some(std::sync::Mutex::new(
77 $crate::backtrace::Backtrace::new_unresolved(),
78 )),
79 #[cfg(not(feature = "backtrace"))]
80 backtrace: None,
81 }
82 }
83
84 #[cfg(feature = "backtrace")]
85 #[cold]
86 fn get_backtrace(&self) -> Option<&std::sync::Mutex<$crate::backtrace::Backtrace>> {
87 self.backtrace.as_ref().map(|mutex| {
88 mutex.lock().unwrap().resolve();
89 mutex
90 })
91 }
92
93 #[cfg(not(feature = "backtrace"))]
94 #[cold]
95 fn get_backtrace(&self) -> Option<&std::sync::Mutex<$crate::backtrace::Backtrace>> {
96 None
97 }
98 }
99
100 impl std::fmt::Debug for ErrorData {
101 #[cfg(feature = "backtrace")]
102 #[cold]
103 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
104 let mut bt = self.backtrace.as_ref().unwrap().lock().unwrap();
105 bt.resolve();
106 write!(f, "{:?}\n\n{}", bt, self.kind)
107 }
108
109 #[cfg(not(feature = "backtrace"))]
110 #[cold]
111 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112 write!(f, "{}", self.kind)
113 }
114 }
115
116 #[derive(Debug, thiserror::Error)]
117 pub struct Error(Box<ErrorData>);
118 impl Error {
119 #[cold]
120 pub fn kind(&self) -> &$Kind {
121 &self.0.kind
122 }
123
124 #[cold]
125 pub fn backtrace(&self) -> Option<&std::sync::Mutex<$crate::backtrace::Backtrace>> {
126 self.0.get_backtrace()
127 }
128 }
129
130 impl std::fmt::Display for Error {
131 #[cold]
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 std::fmt::Display::fmt(self.kind(), f)
134 }
135 }
136
137 impl From<$Kind> for Error {
138 #[cold]
140 fn from(ctx: $Kind) -> Error {
141 Error(Box::new(ErrorData::new(ctx)))
142 }
143 }
144 };
145}
146
147#[macro_export]
151macro_rules! define_error_conversions {
152 ($Kind:ident { $(($variant:ident, $type:ty)),* $(,)? }) => ($(
153 impl From<$type> for Error {
154 #[cold]
156 fn from(e: $type) -> Self {
157 Error::from($Kind::$variant(e))
158 }
159 }
160 )*);
161}
162
163#[macro_export]
166macro_rules! define_error {
167 ($Kind:ident { $(($variant:ident, $type:ty)),* $(,)? }) => {
168 $crate::define_error_wrapper!($Kind);
169 $crate::define_error_conversions! {
170 $Kind {
171 $(($variant, $type)),*
172 }
173 }
174 };
175}
176
177uniffi::setup_scaffolding!("errorsupport");