Panic-control: Test your panics with peace in mind

Recently I tried to test how my code behaves on occurrence of a panic. With only libstd facilities, it turned out to be fraught with problems: panics caused on purpose are cumbersome to distinguish from bona fide errors and assertion failures, and the default panic hook treats any panic as worth reporting it on stderr and even dumping the stack trace depending on the environment. To top it all, unwrap on a thread::Result cannot look into the panic message to include it in the panic message of the calling thread.

I've found no easy-to-use crate that would provide robust solutions to the above, so I decided to write my own: panic-control. It provides the following features:

  • A generic Context type, parameterized with a user-provided type that designates expected panics. Its spawn() method returns a wrapper over JoinHandle that can inspect the panic payload returned by JoinHandle::join() and if it matches the originating Context's parameter type, return it in the statically typed Ok variant signifying an expected panic.

  • Extension trait ThreadResultExt provides std::thread::Result with a method to inspect the string payload of the Err, should one be found, and a variant of unwrap that can propagate the panic message of the child thread.

  • Facilities to augment the panic hook with filters suppressing its invocation when the panic occurs in a given thread, when the panic payload downcasts to a particular type, or determined by a free-form binary predicate closure called with the hook's parameter.

If you have similar issues with testing panics or overriding the panic hook, try this crate for a solution. Feel free to report if the utilities could be improved in any way.

3 Likes