🎓 A1Learner
🔍

Rust Error Kinds

An error kind is a label that says which sort of failure an io error reports. Code can ask an error for its kind and answer each kind in its own way.

Ask the error for its kind

Every io error can report its kind with .kind(). This file is missing, and the error says what kind of failure it was — no crash, just a value:

use std::fs;
let result = fs::read_to_string("/no/such/folder/note.txt");
match result {
    Ok(_) => println!("read it"),
    Err(e) => println!("kind = {:?}", e.kind()),
}

Give each kind its own answer

Match on the kind. A missing file earns a calm default. Any other kind is a real problem. It panics with the error in the message:

use std::fs;
use std::io::ErrorKind;
let text = match fs::read_to_string("/no/such/folder/settings.txt") {
    Ok(t) => t,
    Err(e) if e.kind() == ErrorKind::NotFound => String::from("(no settings yet)"),
    Err(e) => panic!("could not read: {e}"),
};
println!("{text}");

The same job without a match

unwrap_or_else does it without a match. It runs your closure only when the value is Err. What the closure returns becomes the answer:

use std::fs;
let text = fs::read_to_string("/no/such/folder/note.txt").unwrap_or_else(|error| {
    println!("kind was {:?}", error.kind());
    String::from("default note")
});
println!("{text}");

Example

use std::fs;
use std::io::ErrorKind;
fn load_note(path: &str) -> String {
    match fs::read_to_string(path) {
        Ok(text) => text,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => String::from("(no note saved yet)"),
            _ => panic!("could not read the note: {}", error),
        },
    }
}
fn main() {
    println!("{}", load_note("/no/such/folder/note.txt"));
}

Key points

  • The kind is an ErrorKind value: NotFound, PermissionDenied, and more
  • ErrorKind::NotFound means: the file or folder is not there

In this example, load_note tries to read a file that does not exist. read_to_string fails, and the code asks the error for its kind. The kind is NotFound, so instead of stopping, the function returns a friendly default text: (no note saved yet). Any other kind — no permission, for example — falls into the _ arm and panics with the real error in the message. Same function, two very different answers, chosen by the kind of failure.

Note

ErrorKind is for io errors.

Other error types carry their own details — a parse error, for example, describes what was wrong with the text.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

A program opens its settings file and gets ErrorKind::NotFound. What is a sensible reaction?