291. catch_unwind — One Panicking Job Shouldn't Kill the Whole Worker
Job 2 panics and your worker thread dies with it — jobs 3 through 400 never run. std::panic::catch_unwind stops the panic at a boundary you choose.
A panic unwinds until something catches it or the thread dies. In a job loop, “the thread dies” means every queued job after the bad one is silently dropped:
| |
catch_unwind runs a closure and converts any panic inside it into an Err, so the loop survives:
| |
The Err carries the panic payload as Box<dyn Any + Send>. A panic! with a format string stores a String; a bare string literal stores a &'static str — downcast to whichever you expect (or try both) to recover the message.
Three things to know before you reach for it. It’s a boundary tool — thread pools, FFI edges, plugin callbacks — not try/catch for control flow; fallible code should return Result. It can’t catch anything if the build uses panic = "abort". And it doesn’t undo side effects: a panic while holding a lock still poisons it — catch_unwind decides where unwinding stops, and this morning’s clear_poison handles what it left behind.
If you only wanted to observe the panic and pass it on — log and rethrow — use panic::resume_unwind(payload): it continues unwinding with the original payload and skips printing a second panic message.