4 ms·
Error handling in Rust is one of the reasons I went back to Go. It's a lot of mental overhead having to constantly think about all the different types of errors
by c7DJTLrn 5y ago
Error handling in Rust is one of the reasons I went back to Go. It's a lot of mental overhead having to constantly think about all the different types of errors from different crates that could be returned and how to handle them at the caller. I don't want to have to import somebody's hobby crate that claims to make it easier either. In Go it's just dead simple.
I've noticed a lot of Rust discussion is on how to write the code or make the compiler happy which is quite telling. I don't want to spend my time thinking about how to write the code and make the compiler happy - I want to get a problem solved and a ticket closed. Hence why I went back to Go (but I acknowledge these languages have distinct goals).
- TheDong 5y agoI've found that Go has significantly more mental overhead when it comes to error handling than rust does. In Go, I don't have type information to know what kind of error it is. In rust, I can typically just "match err", and let the compiler tell me what error types it could be, and then handle each of them. In go, I always have to read the entire function that returns the error, and any functions it calls, and so on, and then I have to think about how to handle it. Is it an error from the os package, like "os.Open"? Well, maybe I need: if os.IsNotExist(err) { /* handle */ } Is it an error from the net package? I might need: var addrErr *net.AddrError var invalidAddrErr net.InvalidAddrError var otherErr net.Error if errors.As(err, &addrErr) { /* handle addrErr */ } else if errors.As(err, &invalidAddrErr) { /* handle invalidAddrErr */ } else if errors.As(err, &otherErr) { /* some other net error */ } else if errors.Is(err, net.ErrClosed) { /* handle this network error which is _not_ a net.Error */ } Is it an error that used one of the third party error libraries, like "github.com/hashicorp/errwrap"? I may need even more special handling. The fact that "errors.Is" and "errors.As" requires me to know if an error is a "sentinel" one like 'net.ErrClosed', or a struct error, like 'os.PathError', and I have to know if the struct is implementing error on a pointer receiver or not is also really annoying since it means I have to constantly go check error definitions, even if I vaguely remember what errors a function returns. And, what's worse, the type system doesn't help me! It won't tell me if I get any of these things wrong. I can use "errors.Is" and "errors.As" backwards, and the type system won't help. I have no way to determine what errors a function can return without reading hundreds of lines of code. Frankly, Go's error handling has more overhead than almost any other language, and I find it surprising you find it simple. If all I'm doing is bubbling errors up, then rust's "?" operator works fine, and is easier than Go's "if err != nil" boilerplate. If I'm handling errors, rust's features are helpful, and Go is so much mental overhead it usually makes me forget the problem I was trying to solve by the time I've drawn out the full diagram of possible errors something can return up the stack. Usually rust's type-system has enough info that I don't need to read any code to know what errors I need to handle. That's never the case in Go, because idiomatically errors are "type-erased" into the error interface. Oh, and this is all not to mention that go facilitates making unhandle-able errors. If someone returns "errors.New" or "fmt.Errorf", you're stuck with string matching, while rust encourages making typed and handle-able errors. The number of times I've had my go code break because someone reworded an un-exported error string I had to match on is pretty high. Hasn't happened to me in rust yet.
- sa46 5y agoNot a rust aficionado: If you’re using error.As, wouldn’t you need essentially the same logic in Rust to match the error type and get access to the right fields? Seems like the big difference is the compiler knows the variants of the error. The trade off is that Rust modules are tightly coupled by the error type since you have wrap each one into the module’s own error type.
- iknowstuff 5y agoYour reluctance to use a crate which solves the issue you are facing is somewhat antithetical to Rust's crate-centric philosophy. After all, anyhow::Result does "get your problem solved and ticket closed" just the way you want. That being said, in reality it's probably a pretty common sentiment among adopters, especially since the macro crates can slow down compilation. Thankfully, the ergonomics of error handling are indeed under consideration and work is underway to make it all better.
- FridgeSeal 5y ago> It's a lot of mental overhead having to constantly think about all the different types of errors from different crates that could be returned and how to handle them at the caller. If you care about handling errors robustly, you have to care about this stuff at some point, and if you don’t, just use something like Anyhow and never worry again. When I write Rust stuff, I usually start with Anyhow::Result everywhere, then once everything’s built and working and/or we want more finesse over our error handling I progressively swap to ThisError/etc, I find it’s the best mix of utility and ease of writing. > I've noticed a lot of Rust discussion is on how to write the code or make the compiler happy which is quite telling I suspect this is because a lot of people come from other languages, and try to bring the prior languages quirks and idioms with them, quickly discover the stricter compiler flat out doesn’t permit some of them (unlike other languages), then they figure out the idiomatic/closer way and write up their thoughts on the process.
- rustnote 5y agoError handling is one area I way prefer in Rust. It's trivial but having a single line "expect" to throw on some additional text to an error if it doesn't need anything else is really nice. In Go even something really simple might have a bunch of three line error checks everywhere and it just doesn't feel nice to me.
- deleted 5y ago[deleted]