tonic/transport/server/
display_error_stack.rs

1use std::error::Error;
2use std::fmt;
3use std::fmt::{Display, Formatter};
4
5pub(crate) struct DisplayErrorStack<'a>(pub(crate) &'a (dyn Error + 'static));
6
7impl<'a> Display for DisplayErrorStack<'a> {
8    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
9        write!(f, "{}", self.0)?;
10        let mut next = self.0.source();
11        while let Some(err) = next {
12            write!(f, ": {err}")?;
13            next = err.source();
14        }
15        Ok(())
16    }
17}
18
19#[cfg(test)]
20mod tests {
21    use crate::transport::server::display_error_stack::DisplayErrorStack;
22    use std::error::Error;
23    use std::fmt;
24    use std::fmt::{Display, Formatter};
25    use std::sync::Arc;
26
27    #[test]
28    fn test_display_error_stack() {
29        #[derive(Debug)]
30        struct TestError(&'static str, Option<Arc<TestError>>);
31
32        impl Display for TestError {
33            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
34                write!(f, "{}", self.0)
35            }
36        }
37
38        impl Error for TestError {
39            fn source(&self) -> Option<&(dyn Error + 'static)> {
40                self.1.as_ref().map(|e| e as &(dyn Error + 'static))
41            }
42        }
43
44        let a = Arc::new(TestError("a", None));
45        let b = Arc::new(TestError("b", Some(a.clone())));
46        let c = Arc::new(TestError("c", Some(b.clone())));
47
48        assert_eq!("a", DisplayErrorStack(&a).to_string());
49        assert_eq!("b: a", DisplayErrorStack(&b).to_string());
50        assert_eq!("c: b: a", DisplayErrorStack(&c).to_string());
51    }
52}