Error Handling
Result type
Fallible operations return Result<T, E>: either Ok(T) or Err(E). No exceptions; errors are values.
use std::fs::File;
let f = File::open("hello.txt"); // Result<File, std::io::Error>
match f {
Ok(file) => { /* use file */ }
Err(e) => eprintln!("error: {}", e),
}In C#: Like returning a value or throwing; callers use try/catch. In Rust, callers use match or the ? operator.
unwrap and expect
unwrap(): Returns the value inOk, or panics onErr. Use only when you know it cannot fail (e.g. in examples).expect("msg"): Same but prints your message on panic.
let n: i32 = "42".parse().unwrap();
let n: i32 = "42".parse().expect("parse failed");In C#: Similar to assuming no exception; in Rust, prefer handling Err or propagating with ?.
The ? operator
Inside a function that returns Result<T, E> (or Option<T>), ? on a Result means: if Err, return that error; otherwise unwrap the Ok value.
use std::io::Read; // brings the `read_to_string` method into scope
fn read_to_string(path: &str) -> Result<String, std::io::Error> {
let mut s = String::new();
std::fs::File::open(path)?.read_to_string(&mut s)?;
Ok(s)
}Note the use std::io::Read;. The read_to_string method lives on the Read trait, and trait methods are only callable when the trait is in scope. Without that import the code fails to compile with E0599: no method named read_to_string. (You will revisit trait imports in module 12.)
In C#: Similar to not catching an exception and letting it propagate; in Rust the error type is explicit in the return type. When you need a single function to propagate several different error types through ?, see theory/02_propagation_and_panics.md.
Custom error types
You can use your own type as E in Result<T, E>, or use a crate like thiserror / anyhow for richer errors. The idea is the same: return Err(your_error) and let callers or ? propagate it.
In C#: Like throwing a custom exception type; in Rust you return it as a value.
Key takeaway
Use Result<T, E> for fallible operations; handle with match or propagate with ?. Avoid unwrap() in production code; use expect() only when a panic is acceptable.