33 ms·
I feel like error handling in Go is divided between people who have been using the language for a long time, and those who are new to it. If you're used to exce
by teeray 2y ago
I feel like error handling in Go is divided between people who have been using the language for a long time, and those who are new to it. If you're used to exceptions, and languages with some kind of '?' operator, typing `if err != nil` all the time is probably excruciating. They seem to be the most vocal in the survey about wanting beloved error handling features from their favorite languages.
Once you've been using the language for awhile, you begin to dislike the elaborate system of rugs other languages have to sweep errors under. Errors in Go are right there, in your face, and undeniable that the operation you are doing can be faulty somehow. With good error wrapping, you can trace down exactly which of these `if err != nil` blocks generated the error without a stack trace. If it bothers you that much, you can always make a snippet / macro for it in your editor.
- memset 2y agoSuper interested in your approach to error wrapping! It’s a feature I haven’t used much. I tend to use logs with line numbers to point to where errors occur (but that only gets me so far if I’m returning the error from a child function in the call stack.)
- teeray 2y agoSimply wrap with what you were trying to do when the error occurred (and only that, no speculating what the error could be or indicate). If you do this down the call stack, you end up with a progressive chain of detail with strings you can grep for. For example, something like "processing users index: listing users: consulting redis cache: no route to host" is great. Just use `fmt.Errorf("some wrapping: %w", err)` the whole way up. It has all the detail you want with none of the detail you don't need.
- toxik 2y agoSo hand rolled call stack traces? I just don’t understand why this is better than exceptions.
- Swizec 2y agoWhere I've found `?` super helpful in JS/TS and now miss it the most in Python is dealing with nested data structures. ``` if (foo.bar?.baz?.[5]?.bazinga?.value) ``` Is so much nicer than ``` if foo.bar and foo.bar.baz and foo.bar.baz[5] and foo.bar.baz[5].bazinga and foo.bar.baz[5].bazinga.value ``` I honestly don't care which one of those is falsy, my logic is the same either way. This enables you to ergonomically pass around meaningful domain-oriented objects, which is nice. Edit: looks like optional chaining is a separate proposal – https://github.com/golang/go/issues/42847 https://github.com/golang/go/issues/42847
- nonethewiser 2y agoYes, same experience. As someone who learned on python then got deep into Typsecript, this was a major bummer when returning to python. Its funny because when I was a beginner in both I strongly preferred python syntax. I thought it was much simpler.
- new_user_final 2y agoAs I have pointed in in my other comment, you can use following syntax in python, ugly but better than multiple and (I don't use python anymore) if dict.get('key', {}).get('key-nested',{}).get....:
- jon_richards 2y agoEven less pretty for getattr. And then you have a rude awakening about the difference between the missing default behavior of these two functions.
- new_user_final 2y agoYou can use following syntax in python, ugly but better than multiple and (I don't use python anymore) if dict.get('key', {}).get('key-nested',{}).get....:
- jakelazaroff 2y agoI am but one lowly data point, but I've been using Go for a long time and the pervasive `if err != nil` is one of my least favorite parts of the language.
- tdb7893 2y agoYeah I've been using Go for years at multiple companies and I agree. Using multiple lines of code for something that's so common just isn't an efficient use of screen space to me and at a certain point all those lines hurt readability of code.
- kasey_junk 2y agoBig same.
- pjmlp 2y agoThere are also those of us, old enough to have used Assembly as daily programming language, have used Go boilerplate style across many languages during 20+ years, and don't miss the days exceptions were still academic talk, unavailable in mainstream languages.
- madeofpalk 2y agoI appreciate verbose and explicit patterns like this, but what go lacks is the algebraic data types/enum/unions to actually make this more ergonomic and checked. I find it bizzare that go so strongly relies on this pattern, but lacks the features to make sure you actually check for errors.
- javier2 2y ago100% this. The idea is ok, the tooling to actually use it is terrible
- nonethewiser 2y agoIm not really following this. Only somewhat familiar with Go. The pattern we're talking about is returning errors and having to explicitly check for them, right? How does the lack of "algebraic data types/enum/unions" make this pattern un-ergonomic?
- madeofpalk 2y agoError patterns aren't type checked in Go. So you can forget to check an error, not notice, and ship a bug. It compounds with features like zero values and pointers-as-null to make these bugs either subtle or not subtle, but discoverable only at runtime.
- 9rx 2y ago> So you can forget to check an error, not notice, and ship a bug. How would you forget, exactly? Your tests are going to blow in your face should you ever leave out an entire feature from the implementation. If you forgot to document that feature in your tests, which is more likely, then you've created a situation of undefined behaviour, not a bug. You've made no claims as to what should happen. All possible behaviours are equally valid. And no, pattern matching doesn't help you here as you still need to document what happens on those pattern matches. If you forget to document these cases you've still got the very same undefined behaviour. There is no escaping the need for the tests. It's cool that there is nicer syntax, that your editor can warn you of mistakes while you are typing, and that can save time and all that don't get me wrong, but this idea that you are going straight up forget without any notice of your forgetfulness, as fun as a trope as it is, just isn't realistic.
- richbell 2y ago> I feel like error handling in Go is divided between people who have been using the language for a long time, and those who are new to it. If you're used to exceptions, and languages with some kind of '?' operator, typing `if err != nil` all the time is probably excruciating. They seem to be the most vocal in the survey about wanting beloved error handling features from their favorite languages. This implies that the only people who dislike Go's error handling are newbies that "don't get it". Go's error handling is objectively bad for two reasons: 1. You are never forced to check or handle errors. It's easy to accidentally miss an `if err != nil` check, I've seen sages and newbies alike make this mistake. > Errors in Go are right there, in your face, and undeniable that the operation you are doing can be faulty somehow. 2. Repeating `if err != nil` ad nauseam is not handling errors. Knowing the operation can be faulty somehow is a good way of putting it, because in most cases it's difficult — if not impossible — to figure out what specific failures may occur. This is exacerbated by the historical reliance on strings. e.g., Is it a simple issue that can be easily recovered? Is it a fatal error?
- aiono 2y ago> You are never forced to check or handle errors. It's easy to accidentally miss an `if err != nil` check, I've seen sages and newbies alike make this mistake. While I also don't like Go's error handling approach I thought Go compiler gives an error if a variable is unused, in this case `err`. Is this not the case?
- richbell 2y ago> While I also don't like Go's error handling approach I thought Go compiler gives an error if a variable is unused, in this case `err`. Is this not the case? This isn't foolproof. If you're calling multiple methods and reusing `err` it won't give an error because it's technically not unused.
- aiono 2y agoI didn't know that, this seems like a big foot gun tbh
- alekratz 2y agoI'm not a Go programmer, but I feel like I've sort of "grown up" around them as the language has evolved. for a while I thought that the `if err != nil { ... }` was silly to put everywhere. As I've grown and written a lot more code, however, I actually don't see a problem with it. I'd even go as far as to say that it's a good thing because you're acknowledging the detail that an error could have occurred here, and you're explicitly choosing to pass the handling of it up the chain. with exceptions, there can be a lot of hidden behavior that you're just sweeping under the rug, or errors happen that you didn't even think could be raised by a function.
- mherkender 2y agoI mostly agree but I wish it could be more automatic. I like Golang's error system I just wish they'd provide shorthand ways of handling them.