Why Go Can't Try
nexneo
54 points
69 comments
March 02, 2026
Related Discussions
Found 5 related stories in 40.5ms across 3,471 title embeddings via pgvector HNSW
- Why I Vibe in Go, Not Rust or Python riclib · 30 pts · March 22, 2026 · 51% similar
- Solod: Go can be a better C ibobev · 23 pts · March 22, 2026 · 50% similar
- Stop picking my Go version for me ingve · 46 pts · March 28, 2026 · 48% similar
- A case for Go as the best language for AI agents karakanb · 163 pts · March 02, 2026 · 47% similar
- Why is this program erroneously rejected by three C++ compilers? tornikeo · 24 pts · March 14, 2026 · 43% similar
Discussion Highlights (20 comments)
cryptos
My takeaway is that Go almost always prefers simplicity and not so much good software engineering. `nil` without compiler checks is another example, or designing a new language without generics. However the overall simplicity has its own value.
advisedwang
The Go team has discussed syntactic sugar for error handling many times. They're not against it, they're just holding out for a proposal that checks a lot of boxes and makes everyone happy, which hasn't happened yet.
fweimer
It's more complicated. There is no single correct way to check for errors. Some standard library functions can return data and an error: https://pkg.go.dev/io#Reader
kbolino
The author doesn't touch on it, but the bigger problem with things like Foo|Bar as an actual type (rather than as a type constraint) is that every type must have a default/zero value in Go. This has proven to be a difficult problem for all of the proposals around adding sum types, whether they're used as errors or otherwise. For example, to support interface{Foo|Bar} as a reified type, you'd have to tolerate the nil case, which means you either couldn't call any methods even if they're common to Foo and Bar, or else the compiler would have to synthesize some implementation for the nil case, which would probably have to just panic anyway. And an exhaustive type-switch would always have to have "case nil:" (or "default:") and so on.
impure
I really hate it when people try to justify Go’s design decisions. Try would be very useful. The real reason why is because the Go team refuses to take any lesson from any other programming language except for C. That’s why there are so many questionable decision. Also I was a little disappointed there was no mention of panics which are one such questionable decision. Also the author stopped trying to cover up their AI written tracks at the conclusion because you already read it so who cares.
scuff3d
"Here's the uncomfortable truth: a try keyword in Go without fixing the error type is just syntax sugar. You'd get slightly less typing but none of the real benefits - no exhaustiveness checking, no compiler-inferred error sets, no guarantee that you've actually handled every case." ... So what? From what I can tell that's all anyone has asked for in the context of something to just return nil/error up the call stack.
barelysapient
Go got a ton right. Especially for being almost 20 years old. But errors is one thing that needs a v2. I love Zig's enumerable errors and deferErr function.
seethishat
The programmer is explicitly throwing away the error returned by ReadFile (using the underscore) in the criticism of Go. data, _ := os.ReadFile(path) Saying that is not explicit is just wrong.
skywhopper
How utterly arrogant to insist that “every Go developer” wishes the language abandoned its principles in order to add some syntactic sugar to save a few lines of code. No, we don’t all feel a pang of envy at magic keywords that only work in certain function call configurations. Sheesh.
qezz
In Zig you need an allocator to allocate anything, so whenever you need to add some extra information to an error, you pass a diagnostics object as an output argument to a potentially failing function. In this case it becomes a bit harder to compare it to Go's errors, each with pros and cons. I think comparing Go errors to Rust errors would be more fair. There are some articles about the diagnostic pattern in Zig, e.g. [1], [2] [1] https://github.com/ziglang/zig/issues/2647#issuecomment-5898... [2] https://mikemikeb.com/blog/zig_error_payloads/
a-poor
What is broken about the go error type? If anything the fact that it is a simple interface makes the `try` syntax sugar more doable – right? Let's say you have this: ``` part, err := doSomething() if err != nil { return nil, err } data, err := somethingElse(part) if err != nil { return nil, err } return data, nil ``` Then as long as your function followed the contract 0+ returns and then 1 `error` return, that could absolutely be turned into just the 0+ returns and auto-return error. The fact that the `Error` interface is easy to match and extend, plus the common pattern of adding an error as the last return makes this possible. What am I missing here?
chis
These AI written articles carry all the features and appearance of a well reasoned, logical article. But if you actually pause to think through what they're saying the conclusions make no sense. In this case no, it's not the case that go can't add a "try" keyword because its errors are unstructured and contain arbitrary strings. That's how Python works already. Go hasn't added try because they want to force errors to be handled explicitly and locally.
pie_flavor
Everyone compares Go to Rust. This AI-generated slop mentions Rust at the top, then launches into an explanation of how Go is not like Zig, where Rust is also not like Zig, but instead is extremely like Go. This answers no questions at all about the argument people actually participate in.
renehsz
In my experience, writing a few lines to handle errors is really not as big of a deal as a lot of people make it out to be. However, I've seen numerous times how error handling can become burdensome in poorly structured codebases that make failure states hard to manage. Many developers, especially those in a rush, or juniors, or those coming from exception-based languages, tend to want to bubble errors up the call stack without much thought. But I think that's rarely the best approach. Errors should be handled deliberately, and those handlers should be tested. When a function has many ways in which it can fail, I take it as a sign to rethink the design. In almost every case, it's possible to simplify the logic to reduce potential failure modes, minimizing the burden of writing and testing error handling code and thus making the program more robust. To summarize, in my experience, well-written code handles errors thoughtfully in a few distinct places. Explicit error handling does not have to be a burden. Special language features are not strictly necessary. But of course, it takes a lot of experience to know how to structure code in a way that makes error handling easy.
pinkmuffinere
Is it because “do or do not, there is no try”?
tehnub
Why Article By AI?
guilhas
Coming from Java/C# with exceptions Go felt like an improvement Most languages eventually end up confusing 'try-catch', errors, exceptions, handle?, re-throw?... Together with most programmers mixing internal erros, business errors, transient... Creating complex error types with error factories, if and elses... Everything returning the same simple error is simply genious Also a lot of zig posts are tone def like this. "Oh look something so simple and we're the first to think about it. We must be really good"
deathanatos
The plot seems to get real lost in the article. Sure … it is true that Go errors can carry data, and Zig ones perhaps do not, but I don't see how that is what disqualifies a `try` from being possible. Rust's errors are rich, and Rust had `try!` (which is now just `?`). The article's reasoning around rich errors seems equally muddled. > In Zig, there's no equivalent. If both calls fail with error.FileNotFound, the error value alone can't tell you which file was missing. Which is why I'm not a huge fan of Zig's error type … an int cannot convey the necessary context! (Sometime I'd've thought C had so thoroughly demonstrated as bad with, e.g., `mkdir` telling people "No such file or directory." — yeah, no such directory, that's why I'm calling `mkdir` — that all new designs would not be limited to using integer error codes.) But then we go for … > Zig's answer is the Error Return Trace: instead of enriching the error value, the compiler tracks the error's path automatically. But the error's "path" cannot tell you what file was missing, either … > It tells you where the error traveled, not what it means. Rather than enriching the error value, Zig enriches the tooling. Sure … like, again, a true-ish statement (or opinion), but one that just doesn't contribute to the point, I guess? A backtrace is also useful, but having the exact filename is useful, too. It depends on the exact bug that I'm tracking: sometimes the backtrace is what I need, sometimes the name of the missing file is what I need. Having both would be handy, depending on circumstance, and the call stack alone does not tell you the name of the missing file. … how does either prevent a `try` statement? We try to argue that somehow the stdlib would need to change, but I do not see how that can be. It seems like Go could add try, as syntactic sugar for the pattern at the top of the article. (& if the resulting types would have type errored before, they could after sugaring, etc.)
RadiozRadioz
I keep feeling this feeling and it depresses me. I start reading an article and then gradually realise it's a load of AI slop, but by the time I get that realisation I've already wasted several minutes of my life. It's a sinking feeling like I've been duped, but not for anybody's gain - the "author" isn't earning anything from my view, they've just wasted my time for no reason. Even my misfortune is valueless. It happens again and again and again, it's wearing me down. What are we doing here?
OpenWaygate
One reason I don't like JS or others is that they have too many ways to do the same thing, then you'll be challenged which is better and why on interview. Go offers fewer, more explicit options, not only on error handling.