Readit News logoReadit News
shepmaster commented on Error handling in Rust   felix-knorr.net/posts/202... · Posted by u/emschwartz
nilirl · 2 months ago
Just wanted to say, you single handedly made me a rust programmer.

Your answers on stack overflow and your crates have helped me so much. Thank you!

shepmaster · 2 months ago
You are quite welcome; thanks for the kind words!
shepmaster commented on Error handling in Rust   felix-knorr.net/posts/202... · Posted by u/emschwartz
Expurple · 2 months ago
> multiple error variants that reference the same source error type which I always had issues with in `thiserror`.

Huh?

    #[derive(Debug, thiserror::Error)]
    enum CustomError {
        #[error("failed to open a: {0}")]
        A(std::io::Error),
        #[error("failed to open b: {0}")]
        B(std::io::Error),
    }
    
    fn main() -> Result<(), CustomError> {
        std::fs::read_to_string("a").map_err(CustomError::A)?;
        std::fs::read_to_string("b").map_err(CustomError::B)?;
        Ok(())
    }
If I understand correctly, the main feature of snafu is "merely" reducing the boilerplace when adding context:

    low_level_result.context(ErrorWithContextSnafu { context })?;
    // vs
    low_level_result.map_err(|err| ErrorWithContext { err, context })?;
But to me, the win seems to small to justify the added complexity.

shepmaster · 2 months ago
You certainly can use thiserror to accomplish the same goals! However, your example does a little subtle slight-of-hand that you probably didn't mean to and leaves off the enum name (or the `use` statement):

    low_level_result.context(ErrorWithContextSnafu { context })?;
    low_level_result.map_err(|err| CustomError::ErrorWithContext { err, context })?;
Other small details:

- You don't need to move the inner error yourself.

- You don't need to use a closure, which saves a few characters. This is even true in cases where you have a reference and want to store the owned value in the error:

    #[derive(Debug, Snafu)]
    struct DemoError { source: std::io::Error, filename: PathBuf }

    let filename: &Path = todo!();
    result.context(OpenFileSnafu { filename })?; // `context` will change `&Path` to `PathBuf`
- You can choose to capture certain values implicitly, such as a source file location, a backtrace, or your own custom data (the current time, a global-ish request ID, etc.)

----

As an aside:

    #[error("failed to open a: {0}")]
It is now discouraged to include the text of the inner error in the `Display` of the wrapping error. Including it leads to duplicated data when printing out chains of errors in a nicer / structured manner. SNAFU has a few types that work to undo this duplication, but it's better to avoid it in the first place.

shepmaster commented on Error handling in Rust   felix-knorr.net/posts/202... · Posted by u/emschwartz
conaclos · 2 months ago
I accept, however this requires to create many types with corresponding implementations (`impl From`, `impl Display`, ...). This is a lot of boilerplate.
shepmaster · 2 months ago
In addition to the sibling comment mentioning thiserror, I also submit my crate SNAFU (linked in my ancestor comment). Reducing some of the boilerplate is a big reason I enjoy using it.
shepmaster commented on Error handling in Rust   felix-knorr.net/posts/202... · Posted by u/emschwartz
slau · 2 months ago
I disagree that the status quo is “one error per module or per library”. I create one error type per function/action. I discovered this here on HN after an article I cannot find right now was posted.

This means that each function only cares about its own error, and how to generate it. And doesn’t require macros. Just thiserror.

shepmaster · 2 months ago
> I create one error type per function/action

I do too! I've been debating whether I should update SNAFU's philosophy page [1] to mention this explicitly, and I think your comment is the one that put me over the edge for "yes" (along with a few child comments). Right now, it simply says "error types that are scoped to that module", but I no longer think that's strong enough.

[1]: https://docs.rs/snafu/latest/snafu/guide/philosophy/index.ht...

shepmaster commented on Error handling in Rust   felix-knorr.net/posts/202... · Posted by u/emschwartz
mparis · 2 months ago
I'm a recent snafu (https://docs.rs/snafu/latest/snafu/) convert over thiserror (https://docs.rs/thiserror/latest/thiserror/). You pay the cost of adding `context` calls at error sites but it leads to great error propagation and enables multiple error variants that reference the same source error type which I always had issues with in `thiserror`.

No dogma. If you want an error per module that seems like a good way to start, but for complex cases where you want to break an error down more, we'll often have an error type per function/struct/trait.

shepmaster · 2 months ago
Thanks for using SNAFU! Any feedback you'd like to share?
shepmaster commented on Compiler Explorer and the promise of URLs that last forever   xania.org/202505/compiler... · Posted by u/anarazel
shepmaster · 3 months ago
As we all know, Cool URIs don't change [1]. I greatly appreciate the care taken to keep these Compiler Explorer links working as long as possible.

The Rust playground uses GitHub Gists as the primary storage location for shared data. I'm dreading the day that I need to migrate everything away from there to something self-maintained.

[1]: https://www.w3.org/Provider/Style/URI

shepmaster commented on Show HN: Stack Error – ergonomic error handling for Rust   github.com/gmcgoldr/stack... · Posted by u/garrinm
shepmaster · 3 months ago
I hope to read through your crate and examples later, but if you have a chance, I’d be curious to hear your take on how Stack Error differs from my library, SNAFU [1]!

[1]: https://docs.rs/snafu/latest/snafu/index.html

shepmaster commented on A Rust Documentation Ecosystem Review   harudagondi.space/blog/ru... · Posted by u/hyperbrainer
shepmaster · 4 months ago
SNAFU author here, thanks for including my crate! I’ll try to give your review a thorough read through later and incorporate feedback that makes sense.

I do have https://diataxis.fr/ and related stuff open in another tab and keep meaning to figure out how to best apply it for SNAFU.

Out of curiosity, do you recall if you also read the top-level docs[1]? That’s intended to be the main introduction, I actually don’t expect most people to read the user’s guide, unfortunately.

[1]: https://docs.rs/snafu/latest/snafu/index.html

shepmaster commented on Rust’s dependencies are starting to worry me   vincents.dev/blog/rust-de... · Posted by u/chaosprint
jerf · 4 months ago
A strong advantage of that approach is that you don't need to be the core Rust team to do it. Anyone who wants to do this can just start doing it now.
shepmaster · 4 months ago
I agree. Unfortunately, I think that a lot of the people who ask for a bigger standard library really just want (a) someone else to do the work (b) someone they can trust.

The people working on Rust are a finite (probably overextended!) set of people and you can't just add more work to their plate. "Just" making the standard library bigger is probably a non-starter.

I think it'd be great if some group of people took up the very hard work to curate a set of crates that everyone would use and provide a nice façade to them, completely outside of the Rust team umbrella. Then people can start using this Katamari crate to prove out the usefulness of it.

However, many people wouldn't use it. I wouldn't because I simply don't care and am happy adding my dependencies one-by-one with minimal feature sets. Others wouldn't because it doesn't have the mystical blessing/seal-of-approval of the Rust team.

u/shepmaster

KarmaCake day1073February 6, 2011
About
Cofounder of the world's first Rust consultancy[1] — we are available to help you and your company with any and everything related to Rust! We also produce the Rust in Motion video series[2] for Manning.

[1]: http://integer32.com/ [2]: https://www.manning.com/livevideo/rust-in-motion?a_aid=jgoulding&a_bid=6a993c2e

View Original