Skip to content

Error::as_highlighted panics when formatting a JsError with column_number = 0 #422

Open

Description

@xc01
No description provided.

Activity

  1. reopened this on May 27, 2026
  2. changed the title [-]as_highlighted panics when formatting a JsError with column_number = 0[/-] [+]Error::as_highlighted panics when formatting a JsError with column_number = 0[/+] on May 27, 2026
  3. xc01 commented on May 27, 2026

    @xc01
    Author

    Describe the bug

    Error::as_highlighted() assumes that JsStackFrame::column_number is always 1-based.

    If a JsError contains a stack frame with column_number: Some(0), as_highlighted() panics while formatting the error:

    thread '...' panicked at src/error.rs:139:23:
    attempt to subtract with overflow
    

    The panic happens here:

    let col = usize::try_from(f.column_number.unwrap_or(1)).unwrap_or_default();
    let col = col - 1;

    This is an error-reporting path: as_highlighted() is used to output JS errors. Even if column 0 is unexpected metadata, the formatter should fall back to a normal error display instead of turning the original JS error into a Rust panic.

    To Reproduce

    use rustyscript::error::ErrorFormattingOptions;
    use rustyscript::Error;
    
    #[test]
    #[should_panic]
    fn panic_when_highlighting_js_error_with_zero_column() {
        let js_error = deno_core::error::JsError {
            name: Some("ReferenceError".to_string()),
            message: Some("x is not defined".to_string()),
            stack: None,
            cause: None,
            exception_message: "Uncaught ReferenceError: x is not defined".to_string(),
            frames: vec![deno_core::error::JsStackFrame {
                type_name: None,
                function_name: None,
                method_name: None,
                file_name: Some("file:///test.js".to_string()),
                line_number: Some(1),
                column_number: Some(0),
                eval_origin: None,
                is_top_level: Some(true),
                is_eval: false,
                is_native: false,
                is_constructor: false,
                is_async: false,
                is_promise_all: false,
                promise_index: None,
            }],
            source_line: Some("const x = y;".to_string()),
            source_line_frame_index: Some(0),
            aggregated: None,
            additional_properties: vec![],
        };
    
        let err = Error::from(js_error);
        let _ = err.as_highlighted(ErrorFormattingOptions::default());
    }

    Expected behavior

    as_highlighted() should not panic while formatting an error.

    If the column metadata is 0 or otherwise invalid, it should gracefully fall back to a safe column value or to normal non-highlighted error output.

    One possible fix is to avoid subtracting from zero:

    let col = usize::try_from(f.column_number.unwrap_or(1))
        .unwrap_or_default()
        .saturating_sub(1);

    or explicitly treat column_number == 0 as invalid and skip source highlighting.

    Desktop

    OS: Ubuntu 22.04.1
    Version: 0.12.3

    Additional context

    The issue is not that column 0 must be considered a valid source column. The concern is that as_highlighted() is part of the JS error display path, so malformed or edge-case stack-frame metadata should not turn an already captured JavaScript error into a Rust panic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions