Result and recoverable errors
Result and recoverable errors
A typed student mark may still arrive as invalid text. Result
What you’ll learn
- Propagate parsing errors with a compatible Result contract.
- Validate the school range independently of numeric parsing.
Result and recoverable errors in action
80: parse and validate
Eighty parses and passes the range check.
80: parse and validateeighty: parse error
Eighty written as a word fails parsing, so ? returns the mapped error early.
eighty: parse error120: domain error
The text 120 parses successfully but fails the independent domain check.
120: domain error
Separate parsing from school rules
Parse attempts to interpret the text. map_err translates an error into the application’s chosen message, and ? returns early from a compatible Result-returning function when an operation fails. A separate range check is still needed after parsing succeeds.
Work through the Rust program
Save the complete source as main.rs in the Rust environment. No standard input is needed.
Rust 2024 · complete program
fn parse_score(text: &str) -> Result<u32, String> {
let score = text.trim().parse::<u32>().map_err(|_| "Use a whole number".to_string())?;
if score > 100 { return Err("Use a mark from 0 to 100".to_string()); }
Ok(score)
}
fn main() {
for text in ["80", "eighty", "120"] {
match parse_score(text) {
Ok(score) => println!("Score: {score}"),
Err(message) => println!("Check: {message}"),
}
}
}Expected output
Score: 80
Check: Use a whole number
Check: Use a mark from 0 to 100Follow the execution
Eighty parses and passes the range check. Eighty written as a word fails parsing, so ? returns the mapped error early. The text 120 parses successfully but fails the independent domain check. Main handles each Result without terminating the entire report.
Try the complete program in the Rust compiler. For tests, Cargo commands and local files, use the specified local environment.
Try a small variation
Your task: Why is successful parsing not enough to accept 120?
Rust 2024 · complete program
fn parse_score(text: &str) -> Result<u32, String> {
let score = text.trim().parse::<u32>().map_err(|_| "Use a whole number".to_string())?;
if score > 100 { return Err("Use a mark from 0 to 100".to_string()); }
Ok(score)
}
fn main() {
for text in ["80", "eighty", "120"] {
match parse_score(text) {
Ok(score) => println!("Score: {score}"),
Err(message) => println!("Check: {message}"),
}
}
}Worked answer
Parsing establishes that the text represents a u32. It does not establish that the mark meets the school’s permitted 0-to-100 range.
Mistakes and limits to recognize
Panic is usually unsuitable for ordinary invalid user input. Production error types can retain structured information instead of only strings. The ? operator requires a compatible return context; it is not a universal exception handler.
Check your understanding
Apply the rule
Take the idea into your next program
Parsing establishes that the text represents a u32. It does not establish that the mark meets the school’s permitted 0-to-100 range. Panic is usually unsuitable for ordinary invalid user input.
Further reading: the official Rust Book on result and recoverable errors.
Reaching the recap and completing the quizzes are separate milestones.