cli: highlight error source headers as well

Highlighting "{n}: " will help to follow error sources containing multi-line
messages. I'm going to make revset/template alias errors be formatted as plain
error chain.
This commit is contained in:
Yuya Nishihara 2024-03-24 12:57:59 +09:00
parent 0481e67dfd
commit a25cac70b7
3 changed files with 24 additions and 10 deletions

View file

@ -543,15 +543,20 @@ fn print_error_sources(ui: &Ui, source: Option<&dyn error::Error>) -> io::Result
let Some(err) = source else {
return Ok(());
};
if err.source().is_none() {
writeln!(ui.stderr(), "Caused by: {err}")?;
} else {
writeln!(ui.stderr(), "Caused by:")?;
for (i, err) in iter::successors(Some(err), |err| err.source()).enumerate() {
writeln!(ui.stderr(), "{n}: {err}", n = i + 1)?;
}
}
Ok(())
ui.stderr_formatter()
.with_label("error_source", |formatter| {
if err.source().is_none() {
write!(formatter.labeled("heading"), "Caused by: ")?;
writeln!(formatter, "{err}")?;
} else {
writeln!(formatter.labeled("heading"), "Caused by:")?;
for (i, err) in iter::successors(Some(err), |err| err.source()).enumerate() {
write!(formatter.labeled("heading"), "{}: ", i + 1)?;
writeln!(formatter, "{err}")?;
}
}
Ok(())
})
}
fn handle_clap_error(ui: &mut Ui, err: &clap::Error, hints: &[String]) -> io::Result<ExitCode> {

View file

@ -1,8 +1,10 @@
[colors]
"error" = { fg = "default", bold = true }
"error_source" = { fg = "default" }
"warning" = { fg = "default", bold = true }
"hint" = { fg = "default" }
"error heading" = { fg = "red", bold = true }
"error_source heading" = { bold = true }
"warning heading" = { fg = "yellow", bold = true }
"hint heading" = { fg = "cyan", bold = true }

View file

@ -400,6 +400,13 @@ fn test_color_ui_messages() {
Error: There is no jj repo in "."
"###);
// error source
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", ".."]);
insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"
Error: Path ".." is not in the repo "."
Caused by: Invalid component ".." in repo-relative path "../"
"###);
// warning
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["log", "@"]);
insta::assert_snapshot!(stderr, @r###"
@ -418,7 +425,7 @@ fn test_color_ui_messages() {
],
);
insta::assert_snapshot!(stdout, @r###"
8bb159bc30a9859930e567eb9238a7c43ee6744d
167f90e7600a50f85c4f909b53eaf546faa82879
<Error: No commit available> (elided revisions)
0000000000000000000000000000000000000000
"###);