Panic handler
- Rust course
- Expert
- Lesson 35/46
- 4 min
Handle panics with #[panic_handler].
The panic handler
std provides a handler that prints the message and unwinds the stack when a panic happens. In a no_std binary you must write this handler; there must be exactly one and it must never return:
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {} // or: light an LED, reset the CPU, log the error
}There are ready crates too: panic-halt (halt), panic-reset (restart), panic-probe (report to a debugger).
Customizing panics in std
In normal programs panic behaviour is customized with set_hook, and a panic can be caught and recovered from with catch_unwind (for example so one plugin crashing doesn't stop the whole server):
std::panic::set_hook(Box::new(|_| {})); // silence the default message
let sonuc = std::panic::catch_unwind(|| {
panic!("sıfıra bölme");
});
if let Err(e) = sonuc {
let mesaj = e.downcast_ref::<&str>().copied().unwrap_or("?");
println!("yakalandı: {mesaj}");
}catch_unwind isn't an error-handling tool; expected errors should be handled with Result.
Practice Recover from a panic
Silence the default panic message with set_hook. Call panic!("sıfıra bölme") inside catch_unwind, get the payload with downcast_ref::<&str> and print yakalandı: MESSAGE.
Starter code
fn main() {
// buraya yaz
}Sample solution
fn main() {
std::panic::set_hook(Box::new(|_| {}));
let sonuc = std::panic::catch_unwind(|| {
panic!("sıfıra bölme");
});
if let Err(e) = sonuc {
let mesaj = e.downcast_ref::<&str>().copied().unwrap_or("?");
println!("yakalandı: {}", mesaj);
}
}Expected output
yakalandı: sıfıra bölme
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why is the panic handler's return type <code>!</code>?
- For speed
- For debugging
- Execution can't continue after a panic; the handler must never return Correct answer
- Convention
Explanation: The ! (never) type means "this function doesn't return"; it must be an infinite loop, a reset or an abort.
2 Catch the panic
let sonuc = std::panic::____(|| {
panic!("sıfıra bölme");
});
let sonuc = std::panic::catch_unwind(|| {
panic!("sıfıra bölme");
});
Explanation: catch_unwind returns the panic in the closure as an Err.
3 Tool and environment
| Term | Meaning |
|---|---|
#[panic_handler] |
no_std binary |
set_hook |
std, customizes the message |
catch_unwind |
std, catches a panic |
panic-halt |
Ready no_std handler |