Skip to content

Commit cb2ae2e

Browse files
authoredJan 31, 2024
fix(graphical): render cause chains for inner errors (#330)
The default `GraphicalReportHandler` disables the printing of cause chains for any inner errors (errors `related()` to a source diagnostic) when it disables nested footer printing. This results in lost cause chain information when printing with the default report handler.
1 parent 55bfc42 commit cb2ae2e

File tree

2 files changed

+92
-6
lines changed

2 files changed

+92
-6
lines changed
 

‎src/handlers/graphical.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,10 @@ impl GraphicalReportHandler {
317317
ErrorKind::Diagnostic(diag) => {
318318
let mut inner = String::new();
319319

320-
// Don't print footer for inner errors
321320
let mut inner_renderer = self.clone();
321+
// Don't print footer for inner errors
322322
inner_renderer.footer = None;
323+
// Cause chains are already flattened, so don't double-print the nested error
323324
inner_renderer.with_cause_chain = false;
324325
inner_renderer.render_report(&mut inner, diag)?;
325326

@@ -362,19 +363,22 @@ impl GraphicalReportHandler {
362363
parent_src: Option<&dyn SourceCode>,
363364
) -> fmt::Result {
364365
if let Some(related) = diagnostic.related() {
366+
let mut inner_renderer = self.clone();
367+
// Re-enable the printing of nested cause chains for related errors
368+
inner_renderer.with_cause_chain = true;
365369
writeln!(f)?;
366370
for rel in related {
367371
match rel.severity() {
368372
Some(Severity::Error) | None => write!(f, "Error: ")?,
369373
Some(Severity::Warning) => write!(f, "Warning: ")?,
370374
Some(Severity::Advice) => write!(f, "Advice: ")?,
371375
};
372-
self.render_header(f, rel)?;
373-
self.render_causes(f, rel)?;
376+
inner_renderer.render_header(f, rel)?;
377+
inner_renderer.render_causes(f, rel)?;
374378
let src = rel.source_code().or(parent_src);
375-
self.render_snippets(f, rel, src)?;
376-
self.render_footer(f, rel)?;
377-
self.render_related(f, rel, src)?;
379+
inner_renderer.render_snippets(f, rel, src)?;
380+
inner_renderer.render_footer(f, rel)?;
381+
inner_renderer.render_related(f, rel, src)?;
378382
}
379383
}
380384
Ok(())

‎tests/test_diagnostic_source_macro.rs

+82
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,85 @@ fn test_nested_diagnostic_source_is_output() {
194194

195195
assert_eq!(expected, out);
196196
}
197+
198+
#[derive(Debug, miette::Diagnostic, thiserror::Error)]
199+
#[error("A multi-error happened")]
200+
struct MultiError {
201+
#[related]
202+
related_errs: Vec<Box<dyn Diagnostic>>,
203+
}
204+
205+
#[cfg(feature = "fancy-no-backtrace")]
206+
#[test]
207+
fn test_nested_cause_chains_for_related_errors_are_output() {
208+
let inner_error = TestStructError {
209+
asdf_inner_foo: SourceError {
210+
code: String::from("This is another error"),
211+
help: String::from("You should fix this"),
212+
label: (3, 4),
213+
},
214+
};
215+
let first_error = NestedError {
216+
code: String::from("right here"),
217+
label: (6, 4),
218+
the_other_err: Box::new(inner_error),
219+
};
220+
let second_error = SourceError {
221+
code: String::from("You're actually a mess"),
222+
help: String::from("Get a grip..."),
223+
label: (3, 4),
224+
};
225+
let multi_error = MultiError {
226+
related_errs: vec![Box::new(first_error), Box::new(second_error)],
227+
};
228+
let diag = NestedError {
229+
code: String::from("the outside world"),
230+
label: (6, 4),
231+
the_other_err: Box::new(multi_error),
232+
};
233+
let mut out = String::new();
234+
miette::GraphicalReportHandler::new_themed(miette::GraphicalTheme::unicode_nocolor())
235+
.with_width(80)
236+
.with_footer("Yooo, a footer".to_string())
237+
.render_report(&mut out, &diag)
238+
.unwrap();
239+
println!("{}", out);
240+
241+
let expected = r#" × A nested error happened
242+
╰─▶ × A multi-error happened
243+
244+
Error: × A nested error happened
245+
├─▶ × TestError
246+
247+
╰─▶ × A complex error happened
248+
╭────
249+
1 │ This is another error
250+
· ──┬─
251+
· ╰── here
252+
╰────
253+
help: You should fix this
254+
255+
╭────
256+
1 │ right here
257+
· ──┬─
258+
· ╰── here
259+
╰────
260+
Error: × A complex error happened
261+
╭────
262+
1 │ You're actually a mess
263+
· ──┬─
264+
· ╰── here
265+
╰────
266+
help: Get a grip...
267+
268+
╭────
269+
1 │ the outside world
270+
· ──┬─
271+
· ╰── here
272+
╰────
273+
274+
Yooo, a footer
275+
"#;
276+
277+
assert_eq!(expected, out);
278+
}

0 commit comments

Comments
 (0)
Please sign in to comment.