Hacker News new | past | comments | ask | show | jobs | submit login

There is no better way.

The general idea is that you should pay the cost of handling an error right there where you receive one, even if you're just going to return it. This reduces the incremental cost of actually doing something about it.

If you're given an easy way out, a simpler way of just not handling errors, you either won't even consider handling them, or you'll actively avoid any and all error handling, for fear of polluting your happy path.

I can't say I agree with the approach all the time, but I know I'm much more likely to consider the error flow doing it the Go way, even if I'm comstant annoyed by it.




> There is no better way.

Zig's way is better.

Error returning is explicit, error returning is declared in the function signature. Error returning plays nice with defer (there is errdefer) and there is limited sugar (try keyword) that makes life easier.


Agreed. Zig has all the advantages of Go's explicit errors as values without the drawbacks.


I meant in Go. This is not a pissing match.

I personally like it better than exceptions (even if it's much noisier for the 95% common case as another poster put it), both of which I've used enough to appreciate the pros/cons of. But that's about it.

I'll probably never use Zig enough to find out.


> If you're given an easy way out, a simpler way of just not handling errors

Doesn't go offer the simplest way of all to "just not handle errors"? Just ignore them. It is an option. You can ignore them on purpose, you can ignore them by mistake, but you can always simply ignore them.


In practice I want the error propagated to the caller 95% of the time and swallowed 5% of the time. The problem is Go makes me explicitly spell out (and write a unit test case for!) the behavior I almost always want, while the rarely-desired behavior is default.


Yeah, sure.

But ignoring by mistake gets caught by linters, in practice.

And then doing it on purpose is almost as noisy as bubbling it, and sure to raise an eyebrow in code review.

My experience is with exceptions in Java/C#, Go errors, and C++ absl::StatusOr. In theory, I'd favor checked exceptions. In practice, I find that I'm always running away from polluting the happy path and coming up with contrived flow when I want to handle/decorate/whatever some errors but not others, and that giving types to checked exceptions becomes a class hierarchy thing that I've also grown to dislike. Both Go and C++/Abseil are indifferent if noisy to me (and C++ annoys me for plenty other reasons). Maybe elsewhere I'd find options better. Maybe.


Isn’t the reason by chance how try-catch works lexically? I find that as another overlooked billion dollar mistake. It’s not that a happy path gets a crack in it, but the absolute monstrosity of a catch ceremony together with a scope torn between two blocks. “try {} catch {} finally {}” should be “[try] { catch {} finally {} }” absolutely everywhere.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: