Ramblings of an aging IT geek
← Ramblings of an aging IT geek
rust

what rust error handling felt like before anyhow turned up

A short note on the era of hand-rolled error enums and the error-chain crate, and why even a tidy Box<dyn Error> took real effort back then.

A screen of Rust source code

Error handling in Rust right now is more work than people coming from elsewhere expect. There's no blessed crate that just makes the pain go away. You either hand-roll an error enum with a From impl for every variant, which is correct and tedious in equal measure, or you reach for error-chain and learn its macros, or you give up on precision and pass Box<dyn Error> around.

The hand-rolled enum is the honest option. You define your Error, you write impl std::error::Error, you write the Display, and you add a From<io::Error> and a From<ParseIntError> and one more every time you call into a new library. It's all boilerplate the compiler could plausibly generate, but it can't yet, so you write it. The upside is total clarity: every error your function can produce is named in the type.

Box<dyn Error> is the lazy escape, and at the edges of a program, in a main that just needs to bail and print something, it's fine. The ? operator works through it because everything implements Error. The cost is you've thrown away the structure, and a caller can't match on what went wrong without downcasting, which nobody enjoys.

I keep thinking someone will write the crate that makes the common case a one-liner whilst keeping the typed case available. Until then I'll keep writing From impls by hand and muttering. It's not bad, exactly. It's just more ceremony than the language's reputation for ergonomics would lead you to expect.