Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

miette fails silently when span is wrong #219

Closed
mimoo opened this issue Oct 31, 2022 · 8 comments · Fixed by #347
Closed

miette fails silently when span is wrong #219

mimoo opened this issue Oct 31, 2022 · 8 comments · Fixed by #347
Labels
bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed

Comments

@mimoo
Copy link

mimoo commented Oct 31, 2022

OK I now understand why I just get an error message without the full beautiful report:

Screen Shot 2022-10-30 at 7 50 38 PM

it's because my span is wrong. It would have been nice if an error would have been thrown so that it's easier to understand why no report is displayed : o

@Benjamin-L
Copy link
Contributor

Could you send an example of the input that you're providing, so I can try to reproduce this behavior? There are several different ways that a span can be wrong, and I'm not sure exactly what's going on here.

@mimoo
Copy link
Author

mimoo commented Nov 3, 2022

I don't have one anymore, but basically if the span in your error points to an offset that's too far off the size of your source, then this will happen. For example using "" as source, and (4, 5) as span

@reissbaker
Copy link

This bit me too and it was fairly confusing.

@passcod
Copy link

passcod commented Feb 10, 2023

Got hit by that too because I emitted spans which were (start, end) and converting them for the error with .into(), without realising they should have been (start, length).

@zkat zkat added bug Something isn't working help wanted Extra attention is needed good first issue Good for newcomers labels Feb 10, 2023
@zkat
Copy link
Owner

zkat commented Feb 10, 2023

Yeah this doesn't look great. :\

I don't have time to get to it myself right now, but if anyone wants to talk about potential solutions, I'm all for it. It's kinda tricky to figure out what a failure coming from a failure library should even look like (should it panic?)

@passcod
Copy link

passcod commented Feb 10, 2023

Just to have a minimal example, this:

use miette::{Diagnostic, SourceSpan, Result};
use thiserror::Error;

#[derive(Debug, Diagnostic, Error)]
#[error("parse error")]
struct ParseError {
    #[source_code]
    src: &'static str,

    #[label("uh oh")]
    wrong: SourceSpan,
}

fn main() -> Result<()> {
    Err(ParseError {
        src: "did a fucky",
        wrong: (6, 11).into(),
    })?;
    Ok(())
}

outputs:

Error:
  × parse error

while changing the span to (6, 5) outputs:

Error:                
  × parse error
   ╭────
 1 │ did a fucky
   ·       ──┬──
   ·         ╰── uh oh
   ╰────

while using the JSON handler with the first works fine (it happily outputs 'wrong' spans).

@passcod
Copy link

passcod commented Feb 10, 2023

I think there's a number of points to improve on:

  1. Documentation.
    The (1, 2).into() syntax is introduced in the crate doc. The text does mention: "This is a basic byte-offset and length" but this is easy to miss; the code sample only says:
    snip2: (usize, usize), // `(usize, usize)` is `Into<SourceSpan>`!
    I propose changing that to say:
    snip2: (usize, usize), // (offset, length) -- `(usize, usize)` is `Into<SourceSpan>`!
  2. Constructor.
    While using (usize, usize) directly won't benefit, SourceSpan::new() could look like:
    pub fn new(start: impl Into<SourceOffset>, length: impl Into<SourceOffset>) -> Self;
    such that this works:
    SourceSpan::new(6, 5)
    and in your editor, would show up as:
    SourceSpan::new(start: 6, length: 5)
    
    alternatively it could be a new method if that's API-breaking. A new method with an evocative name could also help when there's no IDE/RA.
  3. Error reporting.
    That's the tough one, because as the example above shows, the bug simply appears to not show the snippet if the sourcespan is wrong. As a dev, if you're expecting one, you might try to look a bit further by doing this:
    println!("{:?}", Report::from(ParseError {
        src: "did a fucky",
        wrong: (6, 11).into(),
    }));
    which outputs:
    thread 'main' panicked at 'failed printing to stdout: formatter error', library/std/src/io/stdio.rs:1009:9
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    and if you're really determined, you might try:
    let mut out = String::new();
    miette::GraphicalReportHandler::new().render_report(&mut out, &ParseError {
        src: "did a fucky",
        wrong: (6, 11).into(),
    }).into_diagnostic()?;
    dbg!(out);
    which outputs:
    Error:
      × an error occurred when formatting an argument
    
    As a first step, improving whichever of these errors is possible to make better could help.
  4. Being more forgiving with spans.
    One fairly easy way to avoid a silent error would be to be more forgiving with "invalid" spans: if a span appears to point to outside the source, clamp it to the actual bounds of the source. So for spans which are (start, end) instead of (start, length), the span shown would appear to wrongly extend much further than it should, but it would show. For spans which are entirely outside of the source, the display could perhaps be pointing at the last byte.
  5. Fail inline.
    When the handler detects an invalid span, instead of crashing, it could show as much of the error as it can, but for each invalid span replace the span+label with "BUG: this source span is invalid".

@mimoo
Copy link
Author

mimoo commented Feb 16, 2023

an easy way to fix this is to panic only in debug mode, another idea is to change the error message to say something like "the given span does not correctly fit in the source file"

Nahor added a commit to Nahor/miette that referenced this issue Feb 21, 2024
Fixes: zkat#219

When a snippet couldn't be read (typically because the span didn't fit
within the source code), it and the rest of the diagnostic were silently
dropped, which was confusing to the developer.
Now, in place of the snippet, print an error message with the name of
the failed label and the error it triggered, then proceed with the rest
of the diagnostic (footer, related, ...)
Nahor added a commit to Nahor/miette that referenced this issue Feb 21, 2024
Fixes: zkat#219

When a snippet couldn't be read (typically because the span didn't fit
within the source code), it and the rest of the diagnostic were silently
dropped, which was confusing to the developer.
Now, in place of the snippet, print an error message with the name of
the failed label and the error it triggered, then proceed with the rest
of the diagnostic (footer, related, ...)
@zkat zkat closed this as completed in #347 Feb 21, 2024
zkat pushed a commit that referenced this issue Feb 21, 2024
Fixes: #219

When a snippet couldn't be read (typically because the span didn't fit
within the source code), it and the rest of the diagnostic were silently
dropped, which was confusing to the developer.
Now, in place of the snippet, print an error message with the name of
the failed label and the error it triggered, then proceed with the rest
of the diagnostic (footer, related, ...)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
5 participants