1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use Backtrace;
use Error as StdError;
use async_trait;
/// Async-aware companion trait to [`ForgeError`](crate::error::ForgeError).
///
/// Carries the same sync metadata methods as `ForgeError` plus a single
/// async hook, [`async_handle`](Self::async_handle), that callers can
/// override to run an `await` step (logging, telemetry, cleanup) when
/// an error surfaces in an async context. The default implementation
/// is a no-op — implementors who do not need an async hook can ignore
/// the method entirely.
///
/// # Example
///
/// Requires the `async` cargo feature (which pulls in `async-trait`).
/// The hidden `#[cfg(feature = "async")]` gate means this doctest is
/// only compiled when the feature is enabled — under
/// `cargo test --all-features` it runs; otherwise it is silently
/// skipped.
///
/// ```
/// # #[cfg(feature = "async")] {
/// use error_forge::async_error::AsyncForgeError;
/// use async_trait::async_trait;
/// use std::error::Error as StdError;
///
/// #[derive(Debug)]
/// struct MyAsyncError { message: String }
///
/// impl std::fmt::Display for MyAsyncError {
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// write!(f, "{}", self.message)
/// }
/// }
///
/// impl std::error::Error for MyAsyncError {}
///
/// #[async_trait]
/// impl AsyncForgeError for MyAsyncError {
/// fn kind(&self) -> &'static str { "AsyncExample" }
/// fn caption(&self) -> &'static str { "Async Example Error" }
///
/// // Override the no-op default if you want async behaviour:
/// async fn async_handle(&self) -> Result<(), Box<dyn StdError + Send + Sync>> {
/// // Telemetry, cleanup, etc. would go here.
/// Ok(())
/// }
/// }
/// # }
/// ```
///
/// # Breaking change from `0.9.x`
///
/// In `0.9.x`, [`async_handle`](Self::async_handle) was a required
/// method with no default body, and the [`AppError`](crate::error::AppError)
/// implementation provided a stub that did nothing. In `1.0`,
/// [`async_handle`](Self::async_handle) gains a default no-op body
/// and the stub `AppError` implementation is removed. Implementors
/// who actually want async behaviour override the default; everyone
/// else can derive the trait without writing the method.
/// Type alias for async error-forge results.
pub type AsyncResult<T, E> = Result;