Error handling
The Result
type is the preferred way of handling functions that can fail.
A Result
object must be tested, and never ignored.
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 implementError + Send + Sync + 'static
as well asDisplay
.
The
?
operator should be used to improve readability of code. Thetry!
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
orexpect
, - using
assert
, - an unchecked access to an array,
- integer overflow (in debug mode),
- division by zero,
- large allocations,
- string formatting using
format!
.
Functions or instructions that can cause the code to panic at runtime must not be used.
Array indexing must be properly tested, or the
get
method should be used to return anOption
.
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.
Rust code called from FFI must either ensure the function cannot panic, or use
catch_unwind
or thestd::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.