Error handling

Contents
Errors as enums
Display them
Chain with source
Bubble with ?

Errors as enums

A custom error type is often a plain enum where each variant names one failure. Variants carry no payload here, so matching on them stays trivial. Functions return Result with the success type on the left and the error enum on the right.

#[derive(Debug)] enum AppError { NotFound, Denied, } fn find_user(id: u32) -> Result<String, AppError> { if id == 0 { return Err(AppError::NotFound); } Ok(String::from("ada")) }

Zero means missing here, and anything else maps to a fixed name. Callers match on the two variants and decide what to show. New failures become new variants, so the compiler points at every match that needs an update.

Display them

Result errors print nicely only when the type implements Display. The fmt method receives the value and a buffer, and each arm writes one line of text. The write macro returns a result itself, so each arm result becomes the function result.

use std::fmt; impl fmt::Display for AppError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { AppError::NotFound => write!(f, "not found"), AppError::Denied => write!(f, "access denied"), } } }

With Display in place, println can format the error with empty braces. Users see short sentences instead of debug structs. The next section chains this error with other error types.

Chain with source

The std error trait marks a type as a full error citizen. Its default source method returns nothing, which fits errors with no deeper cause. Boxed trait objects then carry any such error up the call stack while keeping its message.

impl std::error::Error for AppError {} fn open_config() -> Result<String, Box<dyn std::error::Error>> { let text = std::fs::read_to_string("app.conf")?; Ok(text) }

One boxed error type now covers file failures and custom failures together. The question mark converts each concrete error into the box automatically. Callers see a single error type no matter what went wrong inside.

Bubble with ?

The question mark returns early when a result holds an error. Happy path code stays flat instead of nesting inside match blocks. Main itself may return a result, which turns a leftover error into a clean process exit.

fn main() -> Result<(), Box<dyn std::error::Error>> { let text = open_config()?; println!("{}", text); Ok(()) }

Each question mark replaces a whole match that would return Err by hand. Successful values unwrap in place and keep their names. Reserve expect and unwrap for tests and examples, and bubble with question marks in real code.

Next: Traits

Article author: Arthur Isaev

Related articles
Rust
Rust course: zero to hero in 50 lessons
What is Rust and where it runs
Install Rust
cargo new
Your first program
Variables
Numbers
Strings
Booleans
Tuples
Arrays
Vectors
Slices
if and else
match
Loops
Ownership
Borrowing
Lifetimes
Functions
Structs
Enums in Rust
Advanced match in Rust
Option combinators in Rust
Result and the question mark in Rust
Advanced strings in Rust
Vec methods in Rust
HashMaps in Rust
Modules in Rust
Crates and workspaces in Rust
Testing in Rust
Error handling
Traits
Generics
Trait bounds
Closures
Iterators
Smart pointers
Threads
Mutex and Arc
Files
CLI arguments
Environment variables
Diagnostics
Time
Parsing strings
TCP networking
Capstone: wordfreq CLI
Capstone: tiny HTTP server
Modern Rust tour
Hero roadmap: the whole course on one page
Install Rust on Windows 11
Install Rust on Ubuntu
Install Rust on Rocky Linux
Install Rust on macOS
Install Rust on FreeBSD
Rust in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: