gel_errors/
display.rs

1use std::fmt;
2
3use crate::{Error, InternalServerError};
4
5pub struct DisplayError<'a>(&'a Error, bool);
6pub struct VerboseError<'a>(&'a Error);
7
8struct DisplayNum(Option<usize>);
9
10pub fn display_error(e: &Error, verbose: bool) -> DisplayError {
11    DisplayError(e, verbose)
12}
13pub fn display_error_verbose(e: &Error) -> VerboseError {
14    VerboseError(e)
15}
16
17impl fmt::Display for DisplayError<'_> {
18    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19        let DisplayError(ref e, verbose) = self;
20        write!(f, "{e:#}")?;
21        if e.is::<InternalServerError>() || *verbose {
22            if let Some(traceback) = e.server_traceback() {
23                write!(f, "\n  Server traceback:")?;
24                for line in traceback.lines() {
25                    write!(f, "\n      {line}")?;
26                }
27            }
28        }
29        Ok(())
30    }
31}
32
33impl fmt::Display for DisplayNum {
34    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35        match self.0 {
36            Some(x) => x.fmt(f),
37            None => "?".fmt(f),
38        }
39    }
40}
41
42impl fmt::Display for VerboseError<'_> {
43    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44        let e = self.0;
45        writeln!(f, "Error type: {}", e.kind_debug())?;
46        writeln!(f, "Message: {e:#}")?;
47        let pstart = e.position_start();
48        let pend = e.position_end();
49        let line = e.line();
50        let column = e.column();
51        if [pstart, pend, line, column].iter().any(|x| x.is_some()) {
52            writeln!(
53                f,
54                "Span: {}-{}, line {}, column {}",
55                DisplayNum(pstart),
56                DisplayNum(pend),
57                DisplayNum(line),
58                DisplayNum(column)
59            )?;
60        }
61        if let Some(traceback) = e.server_traceback() {
62            writeln!(f, "Server traceback:")?;
63            for line in traceback.lines() {
64                writeln!(f, "    {line}")?;
65            }
66        }
67
68        let attr = e.unknown_headers().collect::<Vec<_>>();
69        if !attr.is_empty() {
70            writeln!(f, "Other attributes:")?;
71            for (k, v) in attr {
72                writeln!(f, "  0x{k:04x}: {v:?}")?;
73            }
74        }
75        Ok(())
76    }
77}