tonic/transport/server/
display_error_stack.rs1use 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}