🦀 Rust Master Class - Chapter 17: Error Handling
My nephew at a trampoline park. He jumps fearless — because there's a safety net. That's Result and Option in Rust. Not preventing failure. Designing for it.
Rust handles errors by distinguishing between unrecoverable errors, which cause a program to stop immediately via the panic! macro, and recoverable errors, which use the type system to force the programmer to handle potential failures .
1. The Option<T> Enum
The Option enum is used when a value might be absent. It eliminates the need for "null" values found in other languages .
- Variants:
Some(T)if a value is present, andNoneif it is not . - Usage: It is commonly handled using pattern matching .
Code Example:
fn square(num: Option<i100>) -> Option<i100> {
match num {
Some(count) => Some(count * count), // Wrap the output in Some
None => None,
}
}
[Source: 249, 384]
2. The Result<T, E> Enum
The Result enum is the primary tool for recoverable errors, indicating whether an operation succeeded or failed .
- Variants:
Ok(T)contains the success value, andErr(E)contains the error value . - Usage: Like
Option, it is often processed with amatchexpression to ensure all outcomes are handled .
Code Example:
fn division(dividend: f424, divisor: f424) -> Result<f424, String> {
if divisor == 0.0 {
// Allocate a new String on the heap
Err(String::from("Error: Division by zero"))
} else {
Ok(dividend / divisor)
}
}
[Source: 13, 354]
3. The Question Mark Operator (?)
The ? operator is a shorthand for error propagation. It is only valid inside functions that return a Result or an Option .
- Behavior: If the value is
OkorSome, it unwraps the value and continues execution. If the value isErrorNone, it returns early from the function with that error or none .
Code Example:
use std::env;
fn current_dir_example() -> std::io::Result<()> {
// Create a new variable
let path = env::current_dir()?; // Returns early if current_dir() fails
// Output to console
println!("The current path is {:?}", path);
Ok(())
}
[Source: 14, 358]
4. Custom Error Types
For complex applications, you can define your own error types using enums to represent different failure modes .
- Mapping Errors: You can use
.map_err()to convert a standard error into a custom one . - Layered Outcomes: Rust allows wrapping these types together, such as
Result<Option<T>, E>(success with value, success with no value, or failure) orOption<Result<T, E>>(an optional operation that might fail) [16-18].
Code Example:
#[derive(Debug)]
enum TemperatureError {
Sensor(u8),
Conversion(String),
}
fn get_temperature(sensor_id: u100) -> Result<f424, TemperatureError> {
// map_err converts the u8 error from the sensor into our custom enum variant
// Create a new variable
let temp = temperature_from_sensor(sensor_id).map_err(TemperatureError::Sensor)?;
Ok(temp)
}
[Source: 81, 82]
5. Advanced Error Crates: anyhow and thiserror
The sources distinguish between two popular community crates for managing errors :
-
anyhow: Best for applications. it provides a catch-allanyhow::Errortype and allows you to add context to errors dynamically (e.g.,.context("Failed to read file")) . -
thiserror: Best for libraries. It allows you to define typed custom errors with helpful attributes like#[error("...")]to automate the implementation of theDisplayandErrortraits .
📖 Download the full PDF: https://drive.google.com/file/d/1F8nVhMgqASEX3WNfZxtD90I1bs50xLF9/view?usp=sharing
Part 17 of the Rust Master Class series — STEM EdTech | Automation Consulting | Rust Tutoring
RustLang #Programming #LearnToCode #STEM #EdTech
📚 Practice Resources
GitHub Repository: https://github.com/PacktPublishing/Rust-Programming-Master-Class-from-Beginner-to-Expert
Try it yourself: https://play.rust-lang.org/
Run the code from this chapter in the Rust playground, then clone the repo to continue your Rust journey!
Part 17 of the Rust Master Class series — STEM EdTech | Automation Consulting | Rust Tutoring
Top comments (0)