expect() is Superior to unwrap()
unwrap()
Rust's unwrap() method is a silent killer in your codebase.
When it panics, you're left with cryptic error messages that provide no
context about why the failure occurred or where in
your logic things went wrong. Rust is about human-first errors, ane we
should be better about this!
let value = some_option.unwrap(); // 💥 Panic: "called `Option::unwrap()` on a `None` value"
This tells us nothing about the business logic failure that led to this panic!
expect() Solution
The expect() method does everything
unwrap() does, but with one crucial improvement: it lets
you provide meaningful context when things go wrong.
let user_id = session.get_user_id()
.expect("User must be logged in to access dashboard");
Now when this panics, you get:
"User must be logged in to access dashboard" - immediately
actionable information!
// Bad: What config? Which field?
let port = config.get("port").unwrap().parse::<u16>().unwrap();
// Good: Clear context for each potential failure
let port = config.get("port")
.expect("Server port must be configured in config.toml")
.parse::<u16>()
.expect("Server port must be a valid number between 1-65535");
// Bad: Which file? Why did it fail?
let contents = std::fs::read_to_string(path).unwrap();
// Good: Clear about what we were trying to do
let contents = std::fs::read_to_string(&config_path)
.expect("Failed to read application config file - check file exists and permissions");
There is no performance difference. Both
unwrap() and expect() compile to identical
code in release builds. The error message is only constructed when the
panic actually occurs.
The argument for unwrap() based on performance is simply
wrong.
// expect() - Almost always the right choice
let value = risky_operation().expect("Business-relevant context here");
// unwrap() - NEVER acceptable. Always use expect().
unwrap() Entirely
Rust should remove unwrap() from the language.
Its existence enables lazy programming and creates a false choice
between "quick and dirty" versus "proper error handling."
When developers have unwrap() available, they take the path
of least resistance. This leads to production code filled with
meaningless panic messages that waste countless hours of debugging time.
expect() does everything unwrap() does, but
better. There is literally no valid reason for unwrap() to
exist when expect() is available with zero performance
overhead.
Remove the temptation. Remove unwrap().
Ban unwrap() from your production code.
Add this to the root of your modules to block on build
#![deny(clippy::unwrap_used)]
Cargo.toml can configure clippy
# Cargo.toml
[lints.clippy]
unwrap_used = "deny"
And
configure Clippy
to disallow unwrap() in tests and constants:
# clippy.toml
allow-unwrap-in-consts = false
allow-unwrap-in-tests = false
allow-expect-in-tests = true
Your future self (and your teammates) will thank you when debugging becomes effortless instead of painful.
A ranty project by yaleman.