Search code examples
rustrust-cargo

Is it possible to use a custom `#[panic_handler]` when running `cargo test`?


I have some unit tests in a Rust project which are based on running a single file. In the event that for some reason the program fails gracefully, my testing infrastructure will print out some details about the failure (such as the filename, and additional test parameters).

I would like this to happen for ungraceful program terminations, a.k.a panics. I am aware and use the Rust #[panic_handler] feature. However, I am unsure if it interferes with other tests that might not need this panic handler, and if it interferes with actual testing infrastructure (e.g. does it break things like should_panic).

Any thoughts on the problem?

I am trying the #[panic_handler] feature for each test, but I am unsure of how "correct" it is.


Solution

  • #[panic_handler] is overkill for this job.

    If you want to print additional information from all panics and do nothing else, you can use the panic hook, controlled by std::panic::set_hook(). The difference from the panic handler is that the panic hook may return, continuing with a unwind or abort — it only controls what happens immediately upon panic, not control flow afterwards.

    Even narrower is catch_unwind(). You can call this from each individual test (it is stack-scoped rather than global), and rather than intervening before unwinding (as the panic handler and panic hook do), it stops unwinding (which you can then resume with resume_unwind() in order to actually record the test failure). The advantage of catch_unwind() is that, since you call it from inside the test code, you can easily use information from that particular test case.

    (catch_unwind() only works if the code is compiled with panic = unwind rather than panic = abort, but that is the default and since this is your tests, not a library, there's no reason for it to be changed out from under you.)