14

I'm seeing this trend in Rust that errors in Result are returned like this:

fn do_something() -> Result<SomeType, Box<dyn std::error::Error>> {
    // ...
}

Why are errors dynamic? Having come from a C++ background and prefering std::variant over classical polymorphism (I'm relatively new to rust), I'm allergic to dynamic allocations, so I use them only when I really have to. I also find Rust's enums awesome to have included variants in them. Can someone please explain why isn't it standard/preferred/common to use errors as enum?

dcow
  • 7,765
  • 3
  • 45
  • 65
The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • Dynamic errors are a better alternative because there is less to type. – Boiethios Sep 26 '19 at 13:26
  • 5
    You're probably looking at user-facing applications, which usually have to deal with multiple error types, and `Box` is a common ground for all of them. This is definitely not something I'd recommend in a library. – E_net4 Sep 26 '19 at 13:29
  • 3
    If you haven't read already [Error Handling in Rust](https://blog.burntsushi.net/rust-error-handling/) by Andrew Gallant is an excellent deep dive and explains different approaches. You can stay strongly typed if you prefer. – Logan Reed Sep 26 '19 at 18:52
  • From the "error handling in rust" link posted by @LoganReed above: "If you’re writing a quick ‘n’ dirty program and feel ashamed about panicking anyway, then you should probably use Box (or Box)" – solstice333 Dec 10 '20 at 21:14

1 Answers1

21

In application code, this is typically done for convenience. Making all error types statically known can be a maintenance nightmare: you have an ever-expanding enum of possible error types, most of which you are never going to try to handle individually. These error types have a way of contaminating type signatures far away from where the error would actually occur. Box<dyn std::error::Error> keeps things very clean and the extra allocation isn't usually a problem because it only happens in the error case.

It's rarer in library crates, but some very generic code cannot possibly know what all of the possible error types can be. It can get very clumsy dealing with a type parameter for errors when composing a number of result types. A complex structure of possible statically-known error combinations can be conveniently collapsed into a single type, Box<dyn std::error::Error>.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204