0

Panic and Result – Handle Errors in Rust

Last Updated on

Errors are a part of Software and Rust has features to terminate an application using the panic macro and handle errors gracefully with the Result enum. There are 2 types of errors – recoverable and unrecoverable. A recoverable error is typically an anticipated problem; while an unrecoverable error is something that disrupts and terminals a program abnormally.

Highlights

These are the highlights of this post.

  • Generate recoverable errors using the panic macro.
  • Generate recoverable error due to the out-of-bounds Vec index.
  • Use profile.release and profile.dev with panic = ‘abort’ to minimize the verbosity of recoverable errors.
  • Generate recoverable errors from within a function using the Result enum and its variants.
  • Use BACKTRACE environment variable.
  • Use the ? operator in a function that returns Result.

Unrecoverable Errors Using Panic

To create an unrecoverable error, we use the panic! macro.

The error terminates the program with the following message.

This error is obviously too verbose and we may not want this especially on release versions when we use the panic macro. We can cut this short by using panic = 'abort' in Cargo.toml both for release and unoptimized versions.

For instance, building an unoptimized binary.

On the other hand, building a release binary.

We can also let Rust create unrecoverable errors when encounters faulty codes try to illegally access something, e.g., access out-of-bounds array index.

When we run these codes, we the following error.

The Result Enum And How To Handle Recoverable Errors

First, how do we generate recoverable errors? With unrecoverable errors, we use the panic! macro. Consider the following function.

To generate a recoverable error from a function, we need to use the Result enum, and its variants – Ok and Err. Now, Our function returns the String value “Turreta loves Rust!” when option is 1; otherwise, it returns a recoverable error.

Next, how do we use this function?

This outputs:

If we pass 2 to the function, we’d get:

Using the match expression could make our codes bloated. We could use the ?  operator. When using this operator, the function call must be in another function that returns Result<T, E>. The other method now has to handle the errors. The new codes are as follows.

Notice we modified the main function to return Result so that we can use the ?  operator within it. The Box<dyn Error> is needed to avoid the E0277 error.

Tested with Rust 1.40.0.

Avatar

Karl San Gabriel

Professional Software Developer