Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error handling

The Result type is the preferred way of handling functions that can fail. A Result object must be tested, and never ignored.

Recommendation LANG-ERRWRAP

A crate can implement its own Error type, wrapping all possible errors. It must be careful to make this type exception-safe (RFC 1236), and implement Error + Send + Sync + 'static as well as Display.

Recommendation LANG-ERRDO

The ? operator should be used to improve readability of code. The try! macro should not be used.

Third-party crates may be used to facilitate error handling. Most of them (notably failure, snafu, thiserror) address the creation of new custom error types that implement the necessary traits and allow wrapping other errors.

Another approach (notably proposed in the anyhow crate) consists in an automatic wrapping of errors into a single universal error type. Such wrappers should not be used in libraries and complex systems because they do not allow developers to provide context to the wrapped error.

Panics

Explicit error handling (Result) should always be preferred instead of calling panic. The cause of the error should be available, and generic errors should be avoided.

Crates providing libraries should never use functions or instructions that can fail and cause the code to panic.

Common patterns that can cause panics are:

  • using unwrap or expect,
  • using assert,
  • an unchecked access to an array,
  • integer overflow (in debug mode),
  • division by zero,
  • large allocations,
  • string formatting using format!.

Rule LANG-NOPANIC

Functions or instructions that can cause the code to panic at runtime must not be used.

Rule LANG-ARRINDEXING

Array indexing must be properly tested, or the get method should be used to return an Option.

FFI and panics

When calling Rust code from another language (for ex. C), the Rust code must be careful to never panic. Stack unwinding from Rust code into foreign code results in undefined behavior.

Rule LANG-FFIPANIC

Rust code called from FFI must either ensure the function cannot panic, or use catch_unwind or the std::panic module to ensure the rust code will not abort or return in an unstable state.

Note that catch_unwind will only catch unwinding panics, not those that abort the process.