mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 22:31:47 +00:00
[red-knot] Print non-string panic payloads and (sometimes) backtraces (#15363)
More refinements to the panic messages for failing mdtests to mimic the output of the default panic hook more closely: - We now print out `Box<dyn Any>` if the panic payload is not a string (which is typically the case for salsa panics). - We now include the panic's backtrace if you set the `RUST_BACKTRACE` environment variable.
This commit is contained in:
parent
b6562ed57e
commit
5f5eb7c0dd
2 changed files with 38 additions and 12 deletions
|
@ -141,10 +141,23 @@ fn run_test(db: &mut db::Db, test: &parser::MarkdownTest) -> Result<(), Failures
|
||||||
Ok(type_diagnostics) => type_diagnostics,
|
Ok(type_diagnostics) => type_diagnostics,
|
||||||
Err(info) => {
|
Err(info) => {
|
||||||
let mut by_line = matcher::FailuresByLine::default();
|
let mut by_line = matcher::FailuresByLine::default();
|
||||||
by_line.push(
|
let mut messages = vec![];
|
||||||
OneIndexed::from_zero_indexed(0),
|
match info.location {
|
||||||
info.info.split('\n').map(String::from).collect(),
|
Some(location) => messages.push(format!("panicked at {location}")),
|
||||||
);
|
None => messages.push("panicked at unknown location".to_string()),
|
||||||
|
};
|
||||||
|
match info.payload {
|
||||||
|
Some(payload) => messages.push(payload),
|
||||||
|
// Mimic the default panic hook's rendering of the panic payload if it's
|
||||||
|
// not a string.
|
||||||
|
None => messages.push("Box<dyn Any>".to_string()),
|
||||||
|
};
|
||||||
|
if let Some(backtrace) = info.backtrace {
|
||||||
|
if std::env::var("RUST_BACKTRACE").is_ok() {
|
||||||
|
messages.extend(backtrace.to_string().split('\n').map(String::from));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
by_line.push(OneIndexed::from_zero_indexed(0), messages);
|
||||||
return Some(FileFailures {
|
return Some(FileFailures {
|
||||||
backtick_offset: test_file.backtick_offset,
|
backtick_offset: test_file.backtick_offset,
|
||||||
by_line,
|
by_line,
|
||||||
|
|
|
@ -1,20 +1,27 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::panic::Location;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct PanicError {
|
pub struct PanicError {
|
||||||
pub info: String,
|
pub location: Option<String>,
|
||||||
|
pub payload: Option<String>,
|
||||||
pub backtrace: Option<std::backtrace::Backtrace>,
|
pub backtrace: Option<std::backtrace::Backtrace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for PanicError {
|
impl std::fmt::Display for PanicError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
writeln!(f, "{}", self.info)?;
|
writeln!(f, "panicked at")?;
|
||||||
if let Some(backtrace) = &self.backtrace {
|
if let Some(location) = &self.location {
|
||||||
writeln!(f, "Backtrace: {backtrace}")
|
write!(f, " {location}")?;
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
if let Some(payload) = &self.payload {
|
||||||
|
write!(f, ":\n{payload}")?;
|
||||||
|
}
|
||||||
|
if let Some(backtrace) = &self.backtrace {
|
||||||
|
writeln!(f, "\nBacktrace: {backtrace}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,11 +41,17 @@ fn install_hook() {
|
||||||
if !should_capture {
|
if !should_capture {
|
||||||
return (*prev)(info);
|
return (*prev)(info);
|
||||||
}
|
}
|
||||||
let info = info.to_string();
|
let payload = if let Some(s) = info.payload().downcast_ref::<&str>() {
|
||||||
|
Some(s.to_string())
|
||||||
|
} else {
|
||||||
|
info.payload().downcast_ref::<String>().cloned()
|
||||||
|
};
|
||||||
|
let location = info.location().map(Location::to_string);
|
||||||
let backtrace = std::backtrace::Backtrace::force_capture();
|
let backtrace = std::backtrace::Backtrace::force_capture();
|
||||||
LAST_PANIC.with(|cell| {
|
LAST_PANIC.with(|cell| {
|
||||||
cell.set(Some(PanicError {
|
cell.set(Some(PanicError {
|
||||||
info,
|
payload,
|
||||||
|
location,
|
||||||
backtrace: Some(backtrace),
|
backtrace: Some(backtrace),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue