ProgramGuru

Result and recoverable errors

Result and recoverable errors

A typed student mark may still arrive as invalid text. Result represents success as Ok(value) and failure as Err(error). It makes a recoverable failure part of the function’s contract rather than pretending every input can produce a valid mark.

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

  1. 80: parse and validate

    Eighty parses and passes the range check.

    80: parse and validate
  2. eighty: parse error

    Eighty written as a word fails parsing, so ? returns the mapped error early.

    eighty: parse error
  3. 120: domain error

    The text 120 parses successfully but fails the independent domain check.

    120: domain error
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.

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 100

Follow 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

Why is successful parsing not enough to accept 120?
Choose one answer. You can try again.

Answer and explanation

Parsing establishes that the text represents a u32.

Parsing establishes that the text represents a u32. It does not establish that the mark meets the school’s permitted 0-to-100 range.

Apply the rule

What does the ? operator do when parsing returns Err inside this Result-returning function?
Choose one answer. You can try again.

Answer and explanation

Returns a compatible error early.

It propagates failure through the function’s return contract.

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.

    Next lesson: Validation, panic and checked access →