mirror of https://github.com/astral-sh/uv
Better rendering for multiline error messages (#17132)
Split out from https://github.com/astral-sh/uv/pull/17110 Indent multiline error messages properly, and add a test with a multiline context and a context below since that combination isn't captured atm. --------- Co-authored-by: Zanie Blue <contact@zanie.dev>
This commit is contained in:
parent
a768a9d111
commit
a5d50a20d2
|
|
@ -6959,6 +6959,9 @@ name = "uv-warnings"
|
||||||
version = "0.0.7"
|
version = "0.0.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
|
"anyhow",
|
||||||
|
"indoc",
|
||||||
|
"insta",
|
||||||
"owo-colors",
|
"owo-colors",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,8 @@ workspace = true
|
||||||
anstream = { workspace = true }
|
anstream = { workspace = true }
|
||||||
owo-colors = { workspace = true }
|
owo-colors = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
anyhow = { workspace = true }
|
||||||
|
indoc = { workspace = true }
|
||||||
|
insta = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,15 @@ macro_rules! warn_user_once {
|
||||||
/// warning: Failed to create registry entry for Python 3.12
|
/// warning: Failed to create registry entry for Python 3.12
|
||||||
/// Caused By: Security policy forbids chaining registry entries
|
/// Caused By: Security policy forbids chaining registry entries
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// error: Failed to download Python 3.12
|
||||||
|
/// Caused by: Failed to fetch https://example.com/upload/python3.13.tar.zst
|
||||||
|
/// Server says: This endpoint only support POST requests.
|
||||||
|
///
|
||||||
|
/// For downloads, please refer to https://example.com/download/python3.13.tar.zst
|
||||||
|
/// Caused by: Caused By: HTTP Error 400
|
||||||
|
/// ```
|
||||||
pub fn write_error_chain(
|
pub fn write_error_chain(
|
||||||
err: &dyn Error,
|
err: &dyn Error,
|
||||||
mut stream: impl std::fmt::Write,
|
mut stream: impl std::fmt::Write,
|
||||||
|
|
@ -88,12 +97,62 @@ pub fn write_error_chain(
|
||||||
err.to_string().trim()
|
err.to_string().trim()
|
||||||
)?;
|
)?;
|
||||||
for source in iter::successors(err.source(), |&err| err.source()) {
|
for source in iter::successors(err.source(), |&err| err.source()) {
|
||||||
|
let msg = source.to_string();
|
||||||
|
let mut lines = msg.lines();
|
||||||
|
if let Some(first) = lines.next() {
|
||||||
|
let padding = " ";
|
||||||
|
let cause = "Caused by";
|
||||||
|
let child_padding = " ".repeat(padding.len() + cause.len() + 2);
|
||||||
writeln!(
|
writeln!(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
" {}: {}",
|
"{}{}: {}",
|
||||||
"Caused by".color(color).bold(),
|
padding,
|
||||||
source.to_string().trim()
|
cause.color(color).bold(),
|
||||||
|
first.trim()
|
||||||
)?;
|
)?;
|
||||||
|
for line in lines {
|
||||||
|
let line = line.trim_end();
|
||||||
|
if line.is_empty() {
|
||||||
|
// Avoid showing indents on empty lines
|
||||||
|
writeln!(&mut stream)?;
|
||||||
|
} else {
|
||||||
|
writeln!(&mut stream, "{}{}", child_padding, line.trim_end())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::write_error_chain;
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use indoc::indoc;
|
||||||
|
use insta::assert_snapshot;
|
||||||
|
use owo_colors::AnsiColors;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn format_multiline_message() {
|
||||||
|
let err_middle = indoc! {"Failed to fetch https://example.com/upload/python3.13.tar.zst
|
||||||
|
Server says: This endpoint only support POST requests.
|
||||||
|
|
||||||
|
For downloads, please refer to https://example.com/download/python3.13.tar.zst"};
|
||||||
|
let err = anyhow!("Caused By: HTTP Error 400")
|
||||||
|
.context(err_middle)
|
||||||
|
.context("Failed to download Python 3.12");
|
||||||
|
|
||||||
|
let mut rendered = String::new();
|
||||||
|
write_error_chain(err.as_ref(), &mut rendered, "error", AnsiColors::Red).unwrap();
|
||||||
|
let rendered = anstream::adapter::strip_str(&rendered);
|
||||||
|
|
||||||
|
assert_snapshot!(rendered, @r"
|
||||||
|
error: Failed to download Python 3.12
|
||||||
|
Caused by: Failed to fetch https://example.com/upload/python3.13.tar.zst
|
||||||
|
Server says: This endpoint only support POST requests.
|
||||||
|
|
||||||
|
For downloads, please refer to https://example.com/download/python3.13.tar.zst
|
||||||
|
Caused by: Caused By: HTTP Error 400
|
||||||
|
");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue