Rust Tutorial · Error Handling · Lesson 19 of 29
Rust panic! and Custom Error Types
When to panic and when to return errors, and how to define error types that callers can match on.
panic! is for bugs
panic! (and unwrap()/expect() on failure) stops the thread: use it for situations that mean the program
itself is wrong. For expected failures (bad input, missing files, network errors), return Result.
Custom error enums
An enum lists the ways an operation can fail; implementing Display and std::error::Error makes it work with
?, Box<dyn Error> and error-reporting libraries:
use std::fmt;
#[derive(Debug)]
enum WithdrawError {
InsufficientFunds { needed: u64, available: u64 },
AccountFrozen,
}
impl fmt::Display for WithdrawError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::InsufficientFunds { needed, available } =>
write!(f, "needed {needed}, only {available} available"),
Self::AccountFrozen => write!(f, "account is frozen"),
}
}
}
impl std::error::Error for WithdrawError {}
fn withdraw(balance: u64, amount: u64, frozen: bool) -> Result<u64, WithdrawError> {
if frozen { return Err(WithdrawError::AccountFrozen); }
balance.checked_sub(amount).ok_or(WithdrawError::InsufficientFunds { needed: amount, available: balance })
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("left: {}", withdraw(100, 30, false)?);
if let Err(e) = withdraw(100, 300, false) { println!("error: {e}"); }
match withdraw(100, 10, true) {
Err(WithdrawError::AccountFrozen) => println!("call support"),
other => println!("{other:?}"),
}
Ok(())
}
Output
left: 70 error: needed 300, only 100 available call support
Run this on your computer — see “Get Started” for setup.
In applications, the anyhow crate simplifies error handling; in libraries, thiserror derives the
boilerplate above.
Test yourself
When should Rust code return Result instead of panicking?
NeverWhen failure is expected, like bad input or a missing fileOnly in librariesOnly in async code
Show answer
Answer: When failure is expected, like bad input or a missing file