turbopack_core/
error.rs

1use std::fmt::{Display, Formatter, Result};
2
3/// Implements [Display] to print the error message in a friendly way.
4/// Puts a summary first and details after that.
5pub struct PrettyPrintError<'a>(pub &'a anyhow::Error);
6
7impl Display for PrettyPrintError<'_> {
8    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
9        let mut i = 0;
10        let mut has_details = false;
11
12        let descriptions = self
13            .0
14            .chain()
15            .map(|cause| cause.to_string())
16            .collect::<Vec<_>>();
17
18        for description in &descriptions {
19            // see turbo-tasks-memory/src/task.rs for the error message
20            let hidden = description.starts_with("Execution of ");
21            if !hidden {
22                let header =
23                    description
24                        .split_once('\n')
25                        .map_or(description.as_str(), |(header, _)| {
26                            has_details = true;
27                            header
28                        });
29                match i {
30                    0 => write!(f, "{header}")?,
31                    1 => write!(f, "\n\nCaused by:\n- {header}")?,
32                    _ => write!(f, "\n- {header}")?,
33                }
34                i += 1;
35            } else {
36                has_details = true;
37            }
38        }
39        if has_details {
40            write!(f, "\n\nDebug info:")?;
41            for description in descriptions {
42                f.write_str("\n")?;
43                WithDash(&description).fmt(f)?;
44            }
45        }
46        Ok(())
47    }
48}
49
50/// Indents all lines after the first one. Puts a dash before the first line.
51struct WithDash<'a>(&'a str);
52
53impl Display for WithDash<'_> {
54    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
55        let mut lines = self.0.lines();
56        if let Some(line) = lines.next() {
57            write!(f, "- {line}")?;
58        }
59        for line in lines {
60            write!(f, "\n  {line}")?;
61        }
62        Ok(())
63    }
64}