Rust Lang

Error Handling in Rust

Error handling is practically the second most common thing for a programmer, except making errors, of course. As a developer, you will encounter scenarios where you need to expect an error and create action if it happens.

Although the compiler will implement default error handling, it is good to understand how to handle errors for custom logic. Error handling will prevent your program from returning undesired output or terminating abnormally.

Let us explore how to handle errors in the Rust programming language.

Rust Error Types

There are two types of errors in Rust:

  1. Recoverable Errors
  2. Unrecoverable Errors

Unrecoverable Errors

Unrecoverable errors refer to the types of errors that cause a program to die or exit abnormally. An example would be accessing an out-of-bound index in an array.

Rust uses the panic! macro to handle unrecoverable errors. Suppose the compiler encounters the panic! macro in your code. It prints the specified messages, cleans up the stack, and terminates the program.

The panic! macro is very useful when you encounter errors from which the program cannot recover.

Take a simple program provided below that illustrates how to use the panic macro:

fn main() {

panic!("I'm Dead!!");

}

Once you execute the previous code, you should get an output as shown below:

Calling panic! causes the program to exit and print the panic method specified.

Backtracing a Panic

Rust allows us to backtrace the source of error using the RUST_BACKTRACE environment variable. Backtracing refers to a list of functions that have been called before the error occurred.

Take the example provided below:

fn main() {
    let vec = vec![1,2,3,4,5];
println!({}, vec[5]);
}

In the previous example, we are attempting to read an out-of-bounds array index. This should cause the program to panic and exit.

An output example output is provided below:

As you can see from the output, the compiler tells us we can use the RUST_BACKTRACE environment variable to get the backtrace of the error.

We can do this using the following command:

$ RUST_BACKTRACE=1 cargo run

This should return the backtrace output as:

This should return a detailed output of how the error happened in your code. For an entirely verbose option, you can use the RUST_BACKTRACE=full.

Recoverable Errors

Typically, you will rarely need to handle unrecoverable errors. To handle recoverable errors in Rust, we use the Result enum, which holds two variants: Ok and Err.

Let us take the following simple program attempting to open a file:

usestd::fs::File;
fnmain() {
let file = File::open("hello.txt");
println!("{:?}", file);
}

The previous code attempts to open a non-existent file. Running the program provided above should return as:

Err(Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." })

However, we can define the action we want if the file does not exist. An example is shown below:

usestd::fs::File;
fnmain() {
let file = File::open("hello.txt");
match file {
Ok(file) => {
println!("file found: {:?}", file)
        },
Err(_error) => {
println!("file not found")
        }
    }
}

Here, we use the match operator to check if the file returned an error or Ok. Then, we take the actions for each case.

We can also use the expect method to create custom error handling specifics.

For example:

usestd::fs::File;
fnmain() {
let file = File::open("hello.txt")
        .expect("Error occurred when reading file");
}

The expect method, which will call the panic macro in an error, is encountered when opening the file.

Closing

This tutorial covered the fundamentals of error handling in the Rust programming language. In addition, this guide discussed the two types of errors: recoverable errors and unrecoverable errors. We hope you found this article helpful. Check the other Linux Hint articles for more tips and information.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list