this post was submitted on 11 Jun 2026
26 points (100.0% liked)

Rust

8057 readers
68 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 3 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
[–] treadful@lemmy.zip 5 points 1 day ago (4 children)

Rust's explicitness and being forced to handle every case is so incredibly frustrating but also feels so right.

Thanks for posting this. I'm still trying to figure out the best technique to error handling in my programs. I just learned about anyhow the other day and kind of starting to work that in.

I'm so tired of having to reshape errors with match statements.

let result = match foo(a, b) {
   Ok(r) => r,
   Err(err) => {
       return Err(MyErrorEnum::Error(err.to_string()));
   }
};

This pattern is an annoying habit I keep finding myself repeating.

[–] KindaABigDyl@programming.dev 6 points 14 hours ago

I think this is more idiomatic:

let result = foo(a, b)
    .map_err(|e| MyErrorEnum::Error(e.to_string()));
[–] gabmus@retrolemmy.com 13 points 23 hours ago* (last edited 23 hours ago) (1 children)

Depending on a usecase you might find that many of your "entrypoint functions" might all share the same error type. For example, if you're making an API backend it's likely gonna be something a status code and a message.

In that case a simple way to avoid having to pattern match every single error is to implement From<DownstreamErrorType> for MyErrorEnum, and just use the ? operator. Example:

fn do_something_with_database() -> Result<Whatever, DatabaseError> { /* ... */ }

impl From<DatabaseError> for MyErrorType { /* ... */ }

// this would be your function
fn api_get_something() -> Result<SomeOtherType, MyErrorType> {
    let data: Whatever = do_something_with_database()?;
    // ...
    Ok(/* ... */)
}

EDIT: this is mentioned in the article already

[–] treadful@lemmy.zip 3 points 22 hours ago (2 children)

It's a little verbose (like most of Rust), but I really like this approach. It'll make a lot of logic easier to reason about. I missed that in the article, so thanks for pointing it out.

[–] ISO@lemmy.zip 3 points 19 hours ago (1 children)

(Didn't read the article.)

It's not a secret approach or anything. thiserror gives you that with a simple #[from] attribute annotation on the relevant error variant on your Error enum (which is what your Error type should be).

In your case, this just works because you're not attaching custom context to your error. Usually, you would want to attach some context, and in that case, .map_err()would obviously still be needed, and that's fine. This idea of having to write as little code as possible is stupid.

Sometimes, attaching context once is sufficient, sometimes it's not. If it's the former, then you can still do From in your bigger error enums which have variants from your smaller error enums (e.g. crate-level Error type with variants trivially wrapping module-level Error types).

[–] treadful@lemmy.zip 1 points 12 hours ago (1 children)

This idea of having to write as little code as possible is stupid.

Is it? Not only is it less work, but generally makes the code way easier to reason about. In this case, instead of just seeing simple function calls explaining the logic flow, you visually have to parse all this weird extra cruft that is generally irrelevant to what the block is doing.

[–] jerkface@lemmy.ca 0 points 11 hours ago* (last edited 11 hours ago) (1 children)

Yes, code golf practiced for any reason other than the sheer joy of it is "stupid." It especially doesn't belong in production code. If typing is really so bad, there are any number of local agents that are competent to finish that map fragment for you.

[–] treadful@lemmy.zip 1 points 3 hours ago

It's not about "sheer joy", nor obfuscation. It's about making code easier to write and easier to grok.

[–] gabmus@retrolemmy.com 4 points 22 hours ago

Well, is it really? The verbose part is converting from an error type to another, which you would likely also do in a language with exceptions in the catch block, or in some giant cursed interceptor thing that does a switch/match on the error type (something I had the displeasure to witness with my own two eyes, multiple times)

[–] Gobbel2000@programming.dev 3 points 21 hours ago (1 children)

There is the map_err method on Result which simplifies this case. But yes, anyhow is still easier if you don't care that much about the error contents.

[–] treadful@lemmy.zip 1 points 12 hours ago

Completely forgot about this one. Think I still like the other approach (implementing From) for most places, but I'll keep this one in mind too, thanks.

[–] calcopiritus@lemmy.world 0 points 14 hours ago (1 children)

That's what ? is for. If you have to do that manually, something is not working correctly.

[–] treadful@lemmy.zip 1 points 12 hours ago (1 children)

That only works if everything has the same error types.

[–] calcopiritus@lemmy.world 4 points 10 hours ago

Or just implement Into for your error type. ? Works for Into