Coding/Learn/rust/error handling result
Rust Foundational Course
01.Introduction to Rust & Memory Safety
02.Formatting, Comments & Macros (println!)
03.Variables, Mutability & Shadowing
04.Scalar & Compound Types (Integers, Floats, Tuples, Arrays)
05.Functions, Parameters & Return Expressions
06.Conditionals & If as an Expression
07.Ownership Rules & Move Semantics
08.References & Borrowing (&T)
09.Mutable References (&mut) & Aliasing XOR Mutability
10.Slices & String Types (&str vs String)
11.Loops in Rust (loop, while, for)
12.Pattern Matching with match Expressions
13.Structs, Associated Functions & Methods (impl)
14.Enums & the Option<T> Type (No Null!)
15.Concise Pattern Matching (if let & let else)
16.Vectors & Growable Collections (Vec<T>)
17.Error Handling with Result<T, E> & the ? Operator
18.Traits, Shared Behavior & Generics
19.Closures & Functional Iterators (map, filter, collect)
20.Capstone: High-Performance In-Memory Log Telemetry Engine
Course Certificate0%

Complete all lessons to earn

LearnError Handling with Result<T, E> & the ? Operator
17 / 20 0%
Lesson 17 of 20
6 mins read

Error Handling with Result<T, E> & the ? Operator

PreviousNext Lesson
In Plain English

Rust separates errors into unrecoverable panics (panic!) and recoverable errors represented by Result<T, E> with variants Ok(T) and Err(E). The ? operator propagates errors up the call stack cleanly without nested match blocks.

The Mental Model

"Result<T, E> is like a certified courier package: you open it and either find the ordered merchandise (Ok) or a return receipt with the reason for failure (Err). The ? operator says: "If this package has an error, hand it immediately to my manager and exit.""

Deep Dive: How It Works

The Result<T, E> Enum: enum Result<T, E> { Ok(T), Err(E) }.

The ? Operator: If Result is Ok(v), unwraps v. If Result is Err(e), returns Err(e) from the enclosing function immediately.

expect() vs unwrap(): expect("custom msg") provides a descriptive crash message if the Result was Err.

Syntax Blueprint

fn parse_num(s: &str) -> Result<i32, ParseIntError> { let n = s.parse::<i32>()?; Ok(n) }

The ? operator replaces verbose match blocks for error propagation.

PointCore Rules to Remember

Point star
Explicit Failure: Functions that can fail must declare Result<T, E> in their signature.
Point star
? Operator: Propagates errors up the call stack in a single character.
Point star
No Hidden Exceptions: Every potential failure point is visible in the type system.

Common Beginner Traps & How to Fix Them

Mistake:Using ? in a function that does not return Result.

Why it happens: The ? operator returns early with Err(e), so the enclosing function signature must return Result.

How to fix: Ensure functions using ? return Result<T, E> or Option<T>.

Pro Tip: Use Result<(), Box<dyn std::error::Error>> in main() to allow using ? directly in your entry point!

Live Interactive Example

Hit Run Code to see it live
Result Propagation and Parsing
Rust 1.78 / rustc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Output Console
Click "Run Code" to view the rendered output.
How it works: Demonstrates handling Ok and Err variants with structured error diagnostics.

Your Turn: Micro Challenge

No pressure! Edit the starter code below and test your solution with instant feedback.

Micro Exercise

Safe division with Result

  • PointWrite fn divide(a: i32, b: i32) -> Result<i32, &'static str> { if b == 0 { Err("Cannot divide by zero") } else { Ok(a / b) } }
  • PointIn main(), match divide(100, 4) and print "Division Result: 25".
1
2
3
4
5
6
7
Sandbox Output
Click "Run & Check" to test your solution.

Finished reading and practicing?

Mark this lesson as completed to update your course progress.

PreviousNext Lesson
Overview100 SheetLearnCertificates