Sabrina Jewson
sabrinajewson.org · Personal blog · on HN since 2022
Sabrina Jewson writes in-depth Rust articles on error handling, lifetimes, async design, and atomic orderings.
What HN saysHN commenters recommend her Modular Errors in Rust post and point to it as a good approach to error types, including one error type per function.
15HN people shared it
6linked it in comments
12stories submitted
153story points
1 year agolast shared
2022people per year2026
Most-shared posts
- 1Modular Errors in Rust6 people · 4 points · first shared 2023 · discussion on HN
- 2Why the “Null” Lifetime Does Not Exist4 people · 4 points · first shared 2023 · discussion on HN
- 3The Better Alternative to Lifetime GATs3 people · 46 points · first shared 2022 · 11 comments on HN
- 4Async destructors, async genericity and completion futures2 people · 72 points · first shared 2022 · 21 comments on HN
- 5"Hygienic" Let Statements in Rust1 people · 25 points · first shared 2024 · discussion on HN
- 6A new diagram-based explanation of Rust/C++20 atomic orderings1 people · 2 points · first shared 2022 · discussion on HN
What HN people wrote when they linked it
conaclos · 2025-08-30
The following articles may also be of interest to the audience:
- The definitive guide to error handling in Rust [0]
- Error Handling for Large Rust Projects - Best Practice in GreptimeDB [1]
- Designing error types in Rust [2]
- Modular Errors in Rust [3]
[0]: https://www.howtocodeit.com/articles/the-definitive-guide-to-rust-erro… [1]: https://greptime.com/blogs/2024-05-07-error-rust [2]: https://mmapped.blog/posts/12-rust-error-handling [3]: https://sabrinajewson.org/blog/errors
mananaysiempre · 2023-05-04
Jokes aside, I can think of a couple of differences:
- For the longest time, languages with typed (“checked”) exceptions lacked any parametric polymorphism worth a damn. That made the typing... less than optimally useful, especially with fallible callbacks. Sum types can borrow all that from the existing language, and you’d feel intensely awkward if you tried to go with untyped errors there (it’s of course still possible, through Dynamic or interface
{} or whatever Rust’s thing is).
Though looking at the boilerplate fest that is the latest Rust (sum-types-based) error handling article posted here[1], I’m not entirely convinced the situation has improved. Perhaps open union types of some sort really are needed? That’s where the algebraic-effects languages seem to be going, anyway.
- Exceptions are more strict about what you can do with them: you can return or you can bind, monadically speaking. If an exception was raised, everything stops until it’s caught. With sum types (concrete ones, not an abstract error monad you can’t run), you are allowed to have several propagation chains at once and manipulate them as data. The lack of that additional flexibility is what makes exceptions (more cheaply?) implementable in terms of stack unwinding.
(Traditionally, stack unwinding is thought of as expensive, but I don’t really see why. Sure SJLJ-induced register spills are bad, and sure table-based unwinding is slow as hell, but a linked list of frames as in Win32 SEH[2] has to be…
Expurple · 2025-06-30
> I create one error type per function/action. I discovered this here on HN after an article I cannot find right now was posted.
It could be this one: https://sabrinajewson.org/blog/errors
epage · 2023-07-22
I appreciated the approach in https://sabrinajewson.org/blog/errors
mplanchard · 2024-12-18
We actually went through the same realization when we started writing Rust a few years ago. The `thiserror` crate makes it easy to just wrap and return an error from some third-party library, like:
#[derive(Debug, thiserror::Error)] enum MyError { #[error(transparent)] ThirdPartyError(#[from] third_party::Error) } Since it derives a `From` implementation, you can use it as easily as:
fn some_function() -> Result<(), MyError> { third_party::do_thing()?; } But if that's happening somewhere deep in your application and you call that function from more than one place, good luck figuring out what it is! You wind up with an error log like `third_party thing failed` and that's it.
Generally, we now use structured error types with context fields, which adds some verbosity as specifying a context becomes required, but it's a lot more useful in error logs. Our approach was significantly inspired by this post from Sabrina Jewson: https://sabrinajewson.org/blog/errors
legerdemain · 2022-05-06
Also in Rust, you have combinations of existing and upcoming language features that make certain conceptually simple designs either outright impossible to implement, or only possible to implement a subset of due to certain barely documented compiler quirks, or impossible to determine whether it is actually possible to implement them without sinking hours of time into dead-end prototyping attempts.
Like, not "Rust doesn't do this," but "there's a 50% chance that Rust can do this, but it might turn out to be impossible after all, and absolutely no one can tell which is which, because the language is just barely not expressive enough, or the compiler doesn't analyze this particular case, and might not until both the borrow checker and the type system receive complete rewrites."
And this, in turn, kind of explains why the Rust standard library and especially the Rust compiler are swimming not just in unsafe code blocks, but code that uses features so unstable and private that you can't even enable them with flags on nightly builds.
[0] https://github.com/rust-lang/rust/pull/96709#issuecomment-1118275010
[1] https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats