Rust Learning Path — Chapter 12. Rust makes failures explicit. Instead of silently ignoring many errors, APIs commonly return Result , forcing callers to decide how failure should be handled.
Recoverable vs unrecoverable errors
Use Result for failures a caller may reasonably recover from, such as a missing file, invalid input, or network failure. panic! is for situations where continuing is not appropriate or an invariant has been violated.
Result
fn divide(a: f64, b: f64) -> Result<f64, String> { if b == 0.0 { Err(String::from("division by zero")) } else { Ok(a / b) } } fn main() { match divide(10.0, 2.0) { Ok(value) => println!("{value}"), Err(error) => eprintln!("Error: {error}"), } }unwrap and expect
let port: u16 = "8080".parse().unwrap(); let port: u16 = "8080".parse().expect("port must be a valid u16");These are convenient when failure truly means the program cannot proceed, but application code should not use them as a substitute for deliberate error handling.
The ? operator
? returns the successful value or propagates the error to the caller.
use std::fs; use std::io; fn load_config() -> Result<String, io::Error> { let content = fs::read_to_string("config.txt")?; Ok(content) }Chaining operations safely
use std::{fs, num::ParseIntError}; fn parse_port(text: &str) -> Result<u16, ParseIntError> { text.trim().parse() } fn main() { match parse_port("8080") { Ok(port) => println!("port={port}"), Err(e) => eprintln!("invalid port: {e}"), } }Option vs Result
| Type | Meaning |
| Option | A value is present or absent. |
| Result | An operation succeeded or failed with an error value. |
Custom errors
#[derive(Debug)] enum ConfigError { MissingPort, InvalidPort, } fn port(value: Option<&str>) -> Result<u16, ConfigError> { let text = value.ok_or(ConfigError::MissingPort)?; text.parse().map_err(|_| ConfigError::InvalidPort) }Mini lab: validate an application port
fn validate_port(text: &str) -> Result<u16, String> { let port: u16 = text .trim() .parse() .map_err(|_| "port is not a valid number".to_string())?; if port == 0 { return Err("port cannot be zero".into()); } Ok(port) }Best practices
- Return errors when the caller can make a meaningful decision.
- Add context to errors rather than hiding the original problem.
- Use ? to keep propagation concise.
- Reserve panic! , unwrap() , and expect() for justified cases.
Next: Chapter 13 — Generics.
Join the discussion
0 CommentsAsk questions, add context, or share what worked.
More from Melochip Editorial
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026Related articles
Learn what Playwright testing is, why modern QA teams use it, how testers can get started, and the major types...
7 min read · Sep 19, 2026
Learn how Kubernetes Deployments and ReplicaSets work with practical YAML, scaling, self-healing, rolling upda...
7 min read · Sep 17, 2026
Learn Kubernetes security best practices with RBAC, Secrets, ServiceAccounts, Pod securityContext, NetworkPoli...
6 min read · Sep 17, 2026
Learn Kubernetes monitoring and logs with kubectl logs, events, metrics-server, top commands, Prometheus, Graf...
5 min read · Sep 17, 2026Stay in the loop. Get new Melochip articles
Receive Melochip article updates when new articles are available. Explicit opt-in only.
No comments yet. Start the discussion.