Error Handling with Result

Result<T, E>, the ? operator, custom error types, and when to panic.

Rust has no exceptions. Operations that can fail return Result<T, E>: Ok(value) or Err(error). The ? operator passes errors up to the caller in one character, and the compiler warns if you ignore a Result. Truly unexpected situations (bugs) panic instead.

Parsing sensor lines

ReadingError lists everything that can go wrong; Display gives each case a message.

ok_or(...)? turns a missing field into an error and returns it immediately.

value.parse()? produces a ParseFloatError, converted into ReadingError by the From implementation.

catch_unwind is used here only to show that indexing past the end panics; normal code lets panics end the program.

Result or panic?

let t: f64 = text.parse().unwrap(); // crashes on bad input let t: f64 = text.parse()?; // or match / map_err

Input from outside the program is expected to be wrong sometimes. Propagate or handle the error instead of panicking.

What does the ? operator do?

On Ok(v) it evaluates to v; on Err(e) it converts e with From into the function's error type and returns it immediately. On Option it returns None early.

When is panicking appropriate?

When a bug or broken invariant is detected (something that should be impossible), in tests, and in quick prototypes — not for expected failures such as invalid user input.