miette
miette copied to clipboard
Multiple trailing newlines
When you get a (very nice looking) miette error you get two trailing newlines, rather than just one. This is causing me some head scratching moments with testing error outputs in downstream applications
Demo
[package]
name = "miette-bug-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
miette = { version = "3.0.0", features = [ "fancy" ] }
thiserror = "1.0.30"
use miette::Diagnostic;
use thiserror::Error;
use miette::{SourceSpan, Result};
fn main() -> Result<()> {
Err(MyErrorType{
src: "Demo".to_string(),
err_span: (2, 3).into(),
snip2: (1, 2)
})?;
return Ok(());
}
#[derive(Diagnostic, Debug, Error)]
#[error("oops")]
#[diagnostic(code(my_lib::random_error))]
pub struct MyErrorType {
// The `Source` that miette will use.
#[source_code]
src: String,
// This will underline/mark the specific code inside the larger
// snippet context.
#[label = "This is the highlight"]
err_span: SourceSpan,
// You can add as many labels as you want.
// They'll be rendered sequentially.
#[label("This is bad")]
snip2: (usize, usize), // (usize, usize) is Into<SourceSpan>!
}
Outputs
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `target/debug/miette-bug-demo`
Error: oops
Diagnostic severity: error
Begin snippet starting at line 1, column 1
snippet line 1: Demo
label starting at line 1, column 1: This is bad
label starting at line 1, column 1: This is the highlight
diagnostic code: my_lib::random_error
I would expect the output to be
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `target/debug/miette-bug-demo`
Error: oops
Diagnostic severity: error
Begin snippet starting at line 1, column 1
snippet line 1: Demo
label starting at line 1, column 1: This is bad
label starting at line 1, column 1: This is the highlight
diagnostic code: my_lib::random_error
With the fancy formatter
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `target/debug/miette-bug-demo`
Error: my_lib::random_error
× oops
╭────
1 │ ╭─▶ Demo
· ││ ─┬
· ││ ╰── This is bad
╰────
and with the characters made visible (for my own sanity)
····Finished·dev·[unoptimized·+·debuginfo]·target(s)·in·0.03s¶
·····Running·`target/debug/miette-bug-demo`¶
Error:·oops¶
····Diagnostic·severity:·error¶
Begin·snippet·starting·at·line·1,·column·1¶
¶
snippet·line·1:·Demo¶
····label·starting·at·line·1,·column·1:·This·is·bad¶
····label·starting·at·line·1,·column·1:·This·is·the·highlight¶
diagnostic·code:·my_lib::random_error¶
¶
I am not 100% sure where this is coming from in the code, there are a lot of writeln's, so I suspect it's a writeln inside a writeln using Display. Maybe it would be possible to just trim that trailing newlines before printing to stderr?
I believe I did this on purpose, but some terminals display it as a BIG space. Happy to change it, though.
There are 2 new lines in your output:
- the latest called
writeln!
inReportHandler::debug
impls - the
eprintln!
that actually outputs tostderr
: https://github.com/rust-lang/rust/blob/bc8ad24020a160e1acd7ac9f7671947dcc01264c/library/std/src/process.rs#L2045
It's deceptively easy in the case of DebugReportHandler
. Just remove the ln
here: https://github.com/zkat/miette/blob/fe77d8c75478e9915a61613ec94b3de0a70e5e26/src/handlers/debug.rs#L57
The graphical and narratable paths are much harder. It's a lot more difficult to find the last line sent to the &mut fmt::Formatter
. AFAIK it's not possible to go back and remove the last 1-2 char(s).
One solution would be to replace all the writeln!(A) ... write[ln]!(B)
with something like write!(A)... writeln!(); write!(B)
.
On the other hand, the diffs are empty lines. It might be easier to just write a more robust output validator.
That was the route I went down in the end, I sort of decided that miette
's job was to make a nice error message output, and it does look better with the newline.
Feel free to close this, my problem is solved.