Hacker News new | ask | show | jobs
by jherico 1316 days ago
Go and Rust both strike me as languages made by people who HATE Java/C++ style exception handling but thought the best way to deal with it was to invent a language that constantly punches you in the face.

the fact that the most popular Go IDE actually has logic to automatically fold and hide the constant error handling boilerplate and that people seem to have no problem with that makes me feel like I'm taking crazy pills.

2 comments

I feel like Rust isn't too bad at it: if you want the almost C++/Java level of wrist strain just use anyhow::Error, remember to put ? after fallible calls and downcast to extract the underlying error.

C++ and Java exceptions have non-local flow and it's hard to determine what function can throw what, so if you do want to add error handling cases you would have to inspect every function to know if it throws or not. Yeah, there's noexcept and checked exceptions but one was a late addition that legacy codebases don't use and the other everyone just does throw new RuntimeException(err) anyway.

After several false starts, Rust mostly got this right with returning

    Result<usefulresult, Error>
from most functions, and using "?" for "If the result of this is Error, do a return of the error". There's also a thing where you can write

    foo().context("useful info about foo")?
and pass some more info with the error.

Plus, most things that work like "open" close when their scope closes, so you don't need all that "defer" stuff.

I would have liked a good error hierarchy like Python 2 had, where there was a clear distinction between program-is-broken errors and errors due to external causes. But Rust didn't get that at the beginning, and now it's too late.

I believe the Context trait is from Anyhow, not part of the base Error trait in Rust.

anyhow::Error really does a good job of smoothing out the finicky bits of Rust error handling, it feels and reads a lot better than Go code to me.

Yes, Context is part of Anyhow. That's a legacy problem. Something like Anyhow should have been the base of almost all errors, but it came too late. If you get error handling wrong at the start of a new language, it's really hard to make changes, because the old format gets baked into everything.
> C++ and Java exceptions have non-local flow and it's hard to determine what function can throw what, so if you do want to add error handling cases you would have to inspect every function to know if it throws or not

In general I agree with you, but Rust is already having this problem by people making liberal use of unwrap.

I haven't seen such a problem with unwrap. Newer people use it but are quickly taught to use Err instead. The only times I use it is unreachable!()
C++ exceptions and Rust Anyhow errors lack stack traces by default, whereas Java exceptions capture them by default, aiding debugging. I'm not sure if Rust spans satisfy the same requirements as stack traces; they seem more built around logging and asynchronous execution, than error handling and synchronous code.
I believe the backtrace API was added to stable rust with the most recent release, and so anyhow backtraces should now be available outside of nightly.
Rust did it well, go just didn't. Maybe because go is the new java.