What
When configured for testing, in Host::call_n, call the new call_with_suppressed_panic_hook to catch panics. call_with_suppressed_panic_hook:
- performs a one-time override of the global panic hook
- wraps the original panic hook
- tracks a thread local contract-call recursion count
- when the recursion count is zero, forwards to the original panic hook, maintaining the original hook's behavior
- when the recursion count is non-zero, does nothing
The call_with_suppressed_panic_hook function is extracted out of the call_n function for easier reading, and gets its own module to avoid many extra cfgs.
Why
The existing code is written to suppress the default printing of the global panic hooks when calling contracts in testing mode; later performing a single panic once all contract executes.
The existing code has race conditions that affect tests running in parallel, causing some tests to not report anything to stdout, and probably causing some tests to fail to suppress the recursive panics.
Known limitations
This is hard to write tests for and I think not worth the effort. Please read carefully.
Unlike the existing code, this version never restores the original panic hook that does not contain the wrapper. Since this is only for test configurations that seems reasonable.