liveBook · Manning

Error

As explained in Learn Rust in a Month of Lunches

Error is the Rust standard trait that classifies error types and supports human-readable descriptions and error-source relationships.

Rust’s `std::error::Error` trait marks a type as an official error type. It requires no methods of its own, but an error must also implement `Debug` and `Display` so programs can show useful information. section 13.2.3

A custom error can be a struct or enum. Add `#[derive(Debug)]`, implement `Display` with `fmt`, and then write `impl std::error::Error {}` for the type. `Display` controls user-facing output, while `Debug` supports diagnostic output. section 13.2.3

Returning different error types

A function that can fail in more than one way can return `Result<String, Box<dyn Error>>`. Each concrete error is placed in a `Box`, allowing the function to return different types through one trait object. The `?` operator can then propagate parsing errors, while `unwrap()` will panic if the final result is `Err`. section 13.2.3

use std::error::Error;
use std::fmt;
 
#[derive(Debug)]
struct ErrorOne;
 
impl Error for ErrorOne {}                                          #1
 
impl fmt::Display for ErrorOne {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "You got the first error!")
    }
}
 
 
#[derive(Debug)]
struct ErrorTwo;
 
impl Error for ErrorTwo {}
 
impl fmt::Display for ErrorTwo {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "You got the second error!")
    }
}
 
fn returns_errors(input: u8) -> Result<String, Box<dyn Error>> {    #2
    match input {
        0 => Err(Box::new(ErrorOne)),                               #3
        1 => Err(Box::new(ErrorTwo)),
        _ => Ok("Looks fine to me".to_string()),                    #4
    }
 
}
 
fn main() {
 
    let vec_of_u8s = vec![0_u8, 1, 80];                             #5
 
    for number in vec_of_u8s {
        match returns_errors(number) {
            Ok(input) => println!("{}", input),
            Err(message) => println!("{}", message),
        }
    }
}

Shows two custom error types implementing Error and Display, then returns either error through Box<dyn Error>. section 13.2.3

The trait becomes useful as the error type inside `Result<T, E>`. `Result` carries either a successful `Ok` value or an `Err` value containing information about what went wrong; using an error type instead of a plain string gives that failure a defined interface. section 5.2.2 section 13.2.3

How Learn Rust in a Month of Lunches covers it

How deep it goes
Explains trait requirements, custom implementations, trait objects, and boxed heterogeneous errors, but not advanced error-source APIs.
Examples
Uses custom struct errors, boxed heterogeneous errors, parsing failures, and formatted Result values.
What it assumes
Assumes familiarity with enums, Result, traits, generics, formatting, and the question mark operator.
What you can do after
Builds custom errors and returns multiple error types through Result<String, Box<dyn Error>>.
How it connects
Connects Error with Result, Box, trait objects, Debug, Display, and the question mark operator.

Also explained in

Compare how 3 books explain Error →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.