Rust
Panic handler
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.
Exercise 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.
Show example 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);
}
}
Test yourself
-
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
- Convention
Show answer
Execution can't continue after a panic; the handler must never return — The ! (never) type means "this function doesn't return"; it must be an infinite loop, a reset or an abort.
-
Catch the panic
let sonuc = std::panic::____(|| {
panic!("sıfıra bölme");
});
Show answer
let sonuc = std::panic::catch_unwind(|| {
panic!("sıfıra bölme");
});
-
Tool and environment
- #[panic_handler]
- no_std binary
- set_hook
- std, customizes the message
- catch_unwind
- std, catches a panic
- panic-halt
- Ready no_std handler
Next lesson: Summary - no_std and embedded