miette icon indicating copy to clipboard operation
miette copied to clipboard

Feature request: Span line limit for diagnostics

Open snowfoxsh opened this issue 10 months ago • 3 comments

Feature Request Introduction

In the realm of software development, the clarity and usability of error messages are paramount. As developers, we often encounter diagnostic messages that are meant to guide us toward resolving syntax errors, runtime exceptions, and logical discrepancies in our code. The miette library in Rust has emerged as a powerful tool for enhancing error handling, offering rich diagnostic information that includes source code snippets, contextual messages, and suggestions for remediation. However, when working with extensive code bases or dealing with errors that span many lines, the length of diagnostic messages can sometimes obscure rather than clarify the issue at hand. Recognizing this challenge, I propose an enhancement to the miette library's diagnostic reporting capabilities, specifically aimed at improving the readability of error messages for long multiline spans.

Example of use

Original Behavior

lexer::unterminated_string

  x hello.ap:26:11 unterminated string
    ,-[2:1]
  1 |     (!a = b) {
  2 | ,-> "string
    : |   ^
    : |   `-- unmatched quote
  3 | |   line1
  4 | |   line2
  5 | |   line3
  6 | |   line4
  7 | |   line5
  8 | |   line6
  9 | |   line7
 10 | |   line8
 11 | |   line9
 12 | |   line10
 13 | |   line11
 14 | |   line12
 15 | |   line13
 16 | |   line14
 17 | |   line15
 17 | |   line16
 18 | |   line17
 19 | |   line18
 20 | |   line19
 21 | |   line20
 22 | |   line21
 23 | |   line22
 24 | |   line23
 25 | |   line24
 26 | |-> line25
    : `---- unmatched quote
    `----
  help: a string literal must end with a matching quote

Proposed Base Behavior

With a max span limit set. A span will not display more than N lines. And instead "truncate" the span to skip lines after it reaches the limit. For example with a span limit of 8 set the previous message would look like this.

lexer::unterminated_string

  x hello.ap:26:11 unterminated string
    ,-[2:1]
  1 |     (!a = b) {
  2 | ,-> "string
    : |   ^
    : |   `-- unmatched quote
  3 | |   line1
  4 | |   line2
  5 | |   line3
... | |   
 22 | |   line21
 23 | |   line22
 24 | |   line23
 26 | |-> line25
    : `---- unmatched quote
    `----
  help: a string literal must end with a matching quote

Possible configuration parameters

This section will be provided "by example" along with a short explanation

~~snip~~

  5 | |   line3
... | |   
 22 | |   line21
 
 ~~snip~~

The examples will alter this part of the above example.

Truncation Separator length

Proposed Default: 1 with separator length set to 3 there would be more space in between the lines

  5 | |   line3
... | | 
... | |   
... | |   
 22 | |   line21

Extended break character

Proposed Default: <Whitespace>

This example explores setting the extended break character to ~

  5 | |   line3
... | | ~ ~ ~ ~ ~
 22 | |   line21

With multiple lines it could look like this

  5 | |   line3
... | | ~ ~ ~ ~ ~
... | | ~ ~ ~ ~ ~
... | | ~ ~ ~ ~ ~
 22 | |   line21

Argument for Implementation

Allowing the user to limit reporting of long spans makes diagnostics much more readable. For some applications the information "in between" is no where near as important as the information close to the bounds of the span. Implementing a feature in miette to limit the length of reported spans addresses a key developer need: succinct and focused error diagnostics. This feature drastically improves error readability, especially in complex codebases, by condensing extensive multiline errors into manageable, focused snippets. Such a capability not only speeds up troubleshooting but also reduces cognitive overload, enabling developers to quickly identify and resolve errors.

Example error from rustc

Precedents, such as the error reporting mechanisms in rustc, underline the importance and effectiveness of this approach. By adopting a similar strategy, miette aligns with best practices in error diagnostics, reinforcing its commitment to a superior developer and error reader experience.

*rustc error example: *

error[E0765]: unterminated double quote string
  --> src\main.rs:21:30
   |
21 |           "{} found `thistoken`", location
   |  ______________________________^
22 | |     ).with_source_code(source);
23 | |
24 | |     Err(error)?;
...  |
27 | |     Ok(())
28 | | }
   | |__^

Proposed Setting Syntax

miette::set_hook(Box::new(|_| {  
    Box::new(
        MietteHandlerOpts::new()
            .max_span_length(/*usize*/)
            .span_length_sep_char(/*char*/) // default < >
            .span_length_break_size(/*usize*/) // default 1
            .build()
 )})).unwrap();

Configurable settings enable developers to tailor error diagnostics to their preferences.

snowfoxsh avatar Mar 31 '24 05:03 snowfoxsh