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

Asserts are nearly undebuggable without a backtrace to the actual panic #359

Open
Dr-Emann opened this issue Feb 5, 2025 · 2 comments
Open
Assignees
Labels
enhancement Improvement of existing features or bugfix k::UI/UX UI (user interface) and UX (user experience) changes
Milestone

Comments

@Dr-Emann
Copy link

Dr-Emann commented Feb 5, 2025

Cucumber-rs intentionally installs a panic handler that does nothing. This makes debugging asserts very difficult if there are multiple possible assert locations, as we're given only the panic message.

e.g.

Rust code

use cucumber::{when, World};

#[derive(Debug, Default, World)]
pub struct PanicWorld;

fn panic_on_5(n: u32) {
    assert_ne!(n, 5);
}

#[when("a panic is raised")]
fn panic_fn(_world: &mut PanicWorld) {
    panic_on_5(1);
    panic_on_5(2);
    panic_on_5(3);
    panic_on_5(4);
    panic_on_5(5);
    panic_on_5(6);
    panic_on_5(7);
    panic_on_5(8);
}

fn main() {
    futures::executor::block_on(PanicWorld::run(
        "tests/spec.feature",
    ));
}

Feature File:

Feature: Panics
  Scenario: Debugging without location info is hard
    When a panic is raised
    Then the output should at least include the line number that failed

Command:

cargo test --test example -- -vvvvvvvv

Expected Behavior:

I expect to be able to get any information on where a failure occurred, ideally with a full backtrace (as an option, it would be okay to only include the panic location by default, but it should be possible to get a full backtrace)

Actual Output:

The output contains the panic message, but no information about where the original panic occurred. The actual panic backtrace simply points to the location of the call to run_and_exit (also: should the tests failing really be a panic or just a non-zero exit code and message?).

Feature: Panics
  Scenario: Debugging without location info is hard
   ✘  When a panic is raised
      Step failed:
      Defined: tests/spec.feature:3:5
      Matched: tests/example.rs:10:1
      Step panicked. Captured output: assertion `left != right` failed
        left: 5
       right: 5
      PanicWorld
[Summary]
1 feature
1 scenario (1 failed)
1 step (1 failed)
thread 'main' panicked at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cucumber-0.21.1/src/cucumber.rs:1287:13:
1 step failed
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9fc6b43126469e3858e2fe86cafb4f0fd5068869/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/9fc6b43126469e3858e2fe86cafb4f0fd5068869/library/core/src/panicking.rs:76:14
   2: core::panicking::panic_display
             at /Users/<user>/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/panicking.rs:269:5
   3: cucumber::cucumber::Cucumber<W,P,I,R,Wr,Cli>::filter_run_and_exit::{{closure}}::panic_cold_display
             at /Users/<user>/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/panic.rs:100:13
   4: cucumber::cucumber::Cucumber<W,P,I,R,Wr,Cli>::filter_run_and_exit::{{closure}}
             at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cucumber-0.21.1/src/cucumber.rs:1287:13
   5: cucumber::cucumber::Cucumber<W,P,I,R,Wr,Cli>::run_and_exit::{{closure}}
             at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cucumber-0.21.1/src/cucumber.rs:1195:57
   6: futures_executor::local_pool::block_on::{{closure}}
             at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-executor-0.3.31/src/local_pool.rs:316:23
   7: futures_executor::local_pool::run_executor::{{closure}}
             at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-executor-0.3.31/src/local_pool.rs:90:37
   8: std::thread::local::LocalKey<T>::try_with
             at /Users/<user>/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:283:12
   9: std::thread::local::LocalKey<T>::with
             at /Users/<user>/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:260:9
  10: futures_executor::local_pool::run_executor
             at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-executor-0.3.31/src/local_pool.rs:86:5
  11: futures_executor::local_pool::block_on
             at /Users/<user>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-executor-0.3.31/src/local_pool.rs:316:5
  12: example::main
             at ./tests/example.rs:23:5
  13: core::ops::function::FnOnce::call_once
             at /Users/<user>/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
@Dr-Emann
Copy link
Author

Dr-Emann commented Feb 5, 2025

As a workaround, I've figured out I can currently add a step that re-enables the default panic hook:

Feature File:

Background:
    Given panics have backtraces

Rust File:

#[given("panics have backtraces")]
fn enable_backtraces(_world: &mut PanicWorld) {
    // Re-Enable real backtraces for panics by reinstalling the default panic hook
    _ = std::panic::take_hook();
}

@tyranron
Copy link
Member

tyranron commented Feb 5, 2025

@Dr-Emann

As a workaround, I've figured out I can currently add a step that re-enables the default panic hook

You also should be able to do this in the before_hook. This also demonstrated in the "Scenario hooks" chapter of the Book. This way you won't mess your .feature files with technical details.


Regarding the original issue, I'll try to look into it after the 0.22.0 release, whether it could be improved.

Thank you for reporting this and the suggestion!

@tyranron tyranron self-assigned this Feb 5, 2025
@tyranron tyranron added enhancement Improvement of existing features or bugfix k::UI/UX UI (user interface) and UX (user experience) changes labels Feb 5, 2025
@tyranron tyranron added this to the next milestone Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement of existing features or bugfix k::UI/UX UI (user interface) and UX (user experience) changes
Projects
None yet
Development

No branches or pull requests

2 participants