Rust Error Handling

Written — Updated
  • error_stack
    • This is my current library of choice for error handling.
    • Not a full replacement for thiserror, but a complement to it.
    • Allows attaching messages to arbitrary errors. No more std::io::Error without the filename.
    • Can collecting multiple errors, useful when running concurrent tasks.
    • Preserves the full stack of errors as they progress between modulgje boundaries, so you can see what actually happened, nicely pretty-printed.
    • To remove printing file locations in error stack, for friendlier user-facing errors:
      • error_stack::Report::install_debug_hook::<Location>(|_, _| {});
  • eyre is a fork of anyhow focused on better error reporting
  • Snafu
    • This is a comprehensive library with a lot of options. The big advantage here is that a lot of care is taken to make rich context information easy to use.
    • #[derive(Debug, Snafu)]
      enum Error {
        #[snafu(display("While doing {}", operation))]
        ErrorType {
          source: AnError,
          backtrace: Backtrace,
          operation: String,
    • This generates an ErrorType structure that can be used to add content to an AnError error. ErrorType contains everything except the source and backtrace fields. This can then be used with the context trait.
      • The context type also uses generics parameterized with Into<OriginalType>, so you don't have to do things like to_string() all over the place.
    • do_it_or_anerror().context(ErrorType{ operation: "doing it" })
    • Source fields can be mapped using #[snafu(source(from(ErrorType, MapFunc)))]
    • Applications may want to enable the backtraces-impl-backtrace-crate feature to capture backtraces. The unstable-backtraces-impl-std feature does the same for Rust's built-in backtraces, but those aren't stabilized yet.
    • The futures feature adds context methods to futures and streams that return Results.

Thanks for reading! If you have any questions or comments, please send me a note on Twitter.