Why Use Structured Errors in Rust Applications?

18 points by runxiyu


kzdnk

How I often write application code is I start with anyhow-like error handling, and then once I find a place where I need to do more fine-grade error handling I move to structured errors.

Also, error handling in Rust is not a solved problem, there are other crates than thiserror and anyhow like snafu or miette.

matklad

I requested a feature in rust-analyzer that would allow previewing #[error(..)] attributes without jumping away from the code that I’m working on

Going to definition in a split is such a convenient tool for these sorts of workflows:

https://matklad.github.io/2024/10/08/two-tips.html#Split-And-Go-To-Definition

Wish I’ve found that workflow years earlier.

andyferris

My favorite out of the approaches I’ve seen is what is happening in Roc: structurally typed enums (polymorphic sum types) with inferred variants. Just create a error tag name at the throw point and the compiler will track it through the program for you. Lightweight and easy yet has the advantages of structured errors.

I don’t think structural types are even on the roadmap for Rust though.

It’s a bit of a pitty Zig couldn’t use a tagged union instead of a bare enum (without custom payload) for its polymorphic error enum. There was an issue about it (https://github.com/ziglang/zig/issues/2647) and AFAICT the recommendation seems to be to have the caller pass in an error context and have the callee mutate and set it to a given variant when a particular error is thrown, which the caller has to manually unwrap given the error code. It sounds like more boilerplate and risk than just using the approach in this article (and I’d even wonder in Zig if its easier to make your own result types and not use the nice error syntax at all, than to create and pass around all this mutable context?).