Live data from Hacker News

Rust error handling

bitfieldconsulting.com

11–20 of 65 posts

Re: Rust error handling

#11
Except for anything more production quality, one needs to lean on third party crates to compose errors without explicitly write tons of boilerplate composing result types.

Something that should be supported directly.

Re: Rust error handling

#12
post #7

Earlier quoted context omitted.

Yeah. The error type requires so much boilerplate that I honestly thought I was stupid and doing something wrong. But nope. Just horrific amounts of boilerplate. Then people who don’t want to engage with ThisError and Anyhow do bullshit hacks like making everything a string that has to be parsed (and don’t provide functions to parse). I get why it is that way, but it feels icky.

> I get why it is that way, but it feels icky. There is no reason it has to be so boilerplate heavy, a lot of it can be fixed but someone has to put in the work. The only technical reason that could hold it back is compile times.

Zig has automatic error unions. No boilerplate at all, but not just a single "error" type. The only downside I see in zig errors is that they can't hold extra data.

Re: Rust error handling

#13
post #5

"Go’s Error Handling Is Perfect, Actually" [1] https://blog.verygoodsoftwarenotvirus.ru/posts/errors-in-go/

> Spend any amount of time in programming circles, and just as the sun rises and falls, you are certain to hear someone complain about error handling in Go. These complaints are, anecdotally, rarely well thought out suggestions on what error handling could or should be like in a language like Go, but often merely boil down to “I don’t like having to look at it”. I read it. The first paragraph dismisses preferences in…

Personally I find it much faster to pinpoint errors in the Go style.

With a stack trace, I have to cross-reference with code (ensuring versions match) and filter out a bunch of irrelevant calls in the stack. It’s not uncommon for the stack trace to end deep in library code with the root cause being many calls removed, making me check through a bunch of call sites to figure out what happened.

In Go if good context is added to errors, an error log is generally enough on its own to make it obvious exactly what went wrong.

Re: Rust error handling

#14
> But, since good programs don’t panic, and neither do good programmers, it’s very rare that using unwrap or expect is actually the right thing to do.

I respectfully disagree.

The assert!() macro is a way to document invariants. It's a bug if a variant is violated. It shouldn't have happened, but if it happens, then there's nothing the user can do except reporting the crash.

The unwrap() and expect() method document the invariant that the None and Err() variants shouldn't occur.

It's fail fast.

You should use error handling only if users would be able to handle the errors.

Tell the end user that the file they wanted to open is not readable, for example. Tell the users of your library that an error happened, like a parse error of a config file. And so on. Tell the users what they can fix themselves.

A bug in your library or program, that's something different. Fail fast! And Rust panics are perfect for that.

Re: Rust error handling

#15
post #11

Except for anything more production quality, one needs to lean on third party crates to compose errors without explicitly write tons of boilerplate composing result types. Something that should be supported directly.

I agree that it's not ideal, but using something like anyhow/l and thiserror honestly doesn't feel _that_ bad.

> Something that should be supported directly.

Rust has "adapted" some crates into stdlib in the past. Are there any efforts to that for error handling?

Re: Rust error handling

#16

It's far from perfect. One of the biggest problems with Rust error handling is that if you want to have explicit error return types encoded in the type system you need to create ad hoc enums for each method that returns an error. If you only use a single error type for all functions you will inevitably have functions returning Results that contain error variants that the function will never actually return but still…

This is true, though the issue of having error variants the function can't return is fairly overblown, because most code doesn't bother handling all error variants individually. Most of the time an error is either propagated upwards (possibly wrapped in another error) or logged. Inspecting the error variants is usually only done if you want to specially handle some of them (such as handling `ErrorKind::NotFound` when deleting a file), rather than exhaustively handling all variants.

Re: Rust error handling

#17
post #15
post #11

Except for anything more production quality, one needs to lean on third party crates to compose errors without explicitly write tons of boilerplate composing result types. Something that should be supported directly.

I agree that it's not ideal, but using something like anyhow/l and thiserror honestly doesn't feel _that_ bad. > Something that should be supported directly. Rust has "adapted" some crates into stdlib in the past. Are there any efforts to that for error handling?

So far only the related traits.

That is the kind of excuse we give in C and C++ land, using static analysis isn't that bad.

Re: Rust error handling

#18

It's far from perfect. One of the biggest problems with Rust error handling is that if you want to have explicit error return types encoded in the type system you need to create ad hoc enums for each method that returns an error. If you only use a single error type for all functions you will inevitably have functions returning Results that contain error variants that the function will never actually return but still…

This is true, though the issue of having error variants the function can't return is fairly overblown, because most code doesn't bother handling all error variants individually. Most of the time an error is either propagated upwards (possibly wrapped in another error) or logged. Inspecting the error variants is usually only done if you want to specially handle some of them (such as handling `ErrorKind::NotFound` when…

We can disagree on it being overblown or not but I think it would be enormously useful to be able to look at a function signature and know exactly how it can fail.

Re: Rust error handling

#19
post #5

"Go’s Error Handling Is Perfect, Actually" [1] https://blog.verygoodsoftwarenotvirus.ru/posts/errors-in-go/

I understand that writer's position that they can't go back and fix it now, but in my mind "We can't very well fix it now" is quite different from perfect. I think such a rationale justifies every choice as equally "perfect" and is thus useless.

Re: Rust error handling

#20

Earlier quoted context omitted.

> I get why it is that way, but it feels icky. There is no reason it has to be so boilerplate heavy, a lot of it can be fixed but someone has to put in the work. The only technical reason that could hold it back is compile times.

Zig has automatic error unions. No boilerplate at all, but not just a single "error" type. The only downside I see in zig errors is that they can't hold extra data.

It's a massive downside. When I was using the JSON parser I found it very annoying that it could only tell me the input JSON was invalid, not where in the input the problem was.
Post reply on HN