1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3#[cfg(feature = "axum")]
6#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
7pub mod axum;
8
9use std::error::Error as StdError;
10
11pub type BoxError = Box<dyn StdError + Send + Sync + 'static>;
14
15pub trait StdErrorExt
17where
18 Self: StdError,
19{
20 fn as_chain(&self) -> String {
27 let mut sources = vec![];
28 sources.push(self.to_string());
29
30 let mut source = self.source();
31 while let Some(s) = source {
32 sources.push(s.to_string());
33 source = s.source();
34 }
35
36 sources.join(": ")
37 }
38
39 fn into_boxed(self) -> BoxError
42 where
43 Self: Sized + Send + Sync + 'static,
44 {
45 self.into()
46 }
47}
48
49impl<T> StdErrorExt for T where T: StdError {}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use thiserror::Error;
55
56 #[derive(Debug, Error)]
57 #[error("outer")]
58 struct Outer(#[source] Inner);
59
60 #[derive(Debug, Error)]
61 #[error("inner")]
62 struct Inner;
63
64 #[test]
65 fn test_as_chain() {
66 let error = Outer(Inner);
67 assert_eq!(error.as_chain(), "outer: inner");
68 }
69
70 #[test]
71 fn test_into_boxed() {
72 let error = Outer(Inner);
73 let error = error.into_boxed();
74 assert_eq!(error.to_string(), "outer");
75 }
76}