Skip to content(if available)orjump to list(if available)

Why Go's Error Handling Is Awesome

Why Go's Error Handling Is Awesome

18 comments

·March 9, 2025

bvrmn

> No hidden control-flows

It's so much fun to `return err` through every layer. Explicit no-op attached to every call, yeah!

> No unexpected uncaught exception logs blowing up your terminal (aside from actual program crashes via panics)

A great opportunity to search a code base for logging messages and reconstruct traces by hand. A real true craft!

> full-control of errors in your code as values you can handle, return, and do anything you want with

Yes, it's a real engineering marvel. Exceptions are so bad at this, you could only catch it and, wait...

> Rust, for example, has a good compromise of using option types and pattern matching to find error conditions, leveraging some nice syntactic sugar to achieve similar results.

Thank you for mentioning Rust, I guess. It's very saddle not to include `try` on the table.

InsideOutSanta

"No unexpected uncaught exception logs blowing up your terminal"

Yeah, this one jumped out to me, too. I like exceptions in my logs when something unexpected happens.

CharlieDigital

Is there some actual proof that Go code is less prone to runtime errors or more maintainable or easier to debug because of this?

Surely, if Go's method of error handling is superior to every other programming language, there must be some meaningful statistical side effects that can be observed to prove it right? Lower rate of runtime errors, faster time to debug errors, etc. Someone out there in academia must have been able to actually measure this effect if it exists?

If not, can team Go stop going on and on about how superior their excess keystrokes are?

throwaway519

Prive has a specific meaning. Are you seeking proveble code like box logic and Haskell?

Or do you seek someone to, rather than prove one screwdriver is less error prone than another, to demonstrate it is?

If so, that would depend on context of screws, wood, lefthandedness. A proof in a special case is especially limited. So a demonstration.

Can you demonstrate Go's method of error hanling for a specific context is superior? Yes, you can.

CharlieDigital

Prove as in statistical evidence that code and teams working with Go yield software that has lower rates of runtime defects, has faster time to debug runtime errors, has improved the productivity of developers because of its obviously superior design and philosophy of error handling, etc.

These are all measurable. Productivity is measurable. Defect rates are measurable. Time to debug is measurable.

If there's a peer reviewed paper, let's see it. If there's not, you should produce it and get hired by the Go team!

If this is indeed the superior way of handling errors:

   varFoo, err := GetFoo()
   if err != nil {
     return err
   }
and not just excess key strokes and preference of style, then there will be some statistical side effect that can be measured to prove its superiority. If you can't prove it, all you're saying is "I prefer purple because purple is obviously superior to blue! Can't you see!"...O...K.

null

[deleted]

lolinder

You're being pedantic, and as is often the case when people are pedantic you're also wrong [0]. Their use of the word "prove" is entirely consistent with standard definitions, and "demonstrate" is listed as a synonym for "prove".

> Can you demonstrate Go's method of error hanling for a specific context is superior? Yes, you can.

Then please do! Articles like this one are entirely subjective and anecdote-oriented, not evidence-based proofs (or demonstrations if you like).

[0] https://www.merriam-webster.com/dictionary/prove

akdor1154

You would probably see a bunch of blog posts about 'how we saved 3000% of our SRE time by switching from Go to NodeJS'.

Have you seen many of those?

Aside from this it's probably quite difficult to measure! Sure there are a bunch of metrics you can capture, but unless you're really doing a randomised controlled trial, you will have an absolute dog's breakfast of confounded observational data - good luck getting much useful out of that.

CharlieDigital

Hey, it would make for an excellent doctoral thesis for anyone in a CS program interested in programming languages and productivity...and a great gateway to get hired by Google!

I don't think it would be hard to measure at all.

Randomize some CS students into Go and non-Go and see which teams produce projects with lower rates of defect and faster time to submission. Try it with teams in enterprises; I'm 100% certain that this kind of statistical evidence is meaningful to some CTO/CIO somewhere. Prove to the entire world that everyone should be using Go because it will lead to cost savings not just in time to market, but also less downtime and defects. The financial benefits would be enormous! Possibly billions if not trillions of dollars of productivity gained, system downtime avoided, and runtime defects eliminated ("what runtime defects?") because of the inherent superiority of:

    varFoo, err := GetFoo()
    if err != nil {
        return err
    }
Billions!

MattPalmer1086

Errors do not only happen because of code defects, they are often a response to bad data. And even if there were fewer defects, that could be because of other features of Go, not the error handling.

So that doesn't seem like a good metric to determine if Go's error handling is "better" (in some dimension) than other techniques.

frou_dh

This starts off immediately with in-group/out-group tribal mindset:

> Go's infamous error handling has caught quite the attention from outsiders to the programming language, often touted as one of the language's most questionable design decisions.

> Although it may seem redundant and unnecessary for those new to the language

I have plenty Go experience, yet think the lack of sum-types is iffy. But I don't identify as a true-blue "gopher" so I guess I must be an outsider that just doesn't get it.

lolinder

> However, in other languages, it may not be clear that your code is not handling a potential exception in a try catch code block, being completely opaque about handling your control flow.

In other words, Go's error handling is an even less ergonomic way to do checked exceptions than Java's checked exceptions.

I'm of the opinion that Java was right all along and they just didn't have the inference tools to make it ergonomic at the time, but I'm in a tiny minority there, and most of this article could have been swapped out as a defense of checked exceptions, while the rest is a subjective defense of the syntax.

And then there are the things that checked exceptions give you that Go's errors don't:

* Automatic stack traces. No need to decide that the error is "actionable to developers" and remember to load a library and wrap the error, errors have stack traces. I can't emphasize this enough.

* You can opt out of the line-by-line exception handling by just declaring that your function can throw. The line-by-line manual handling is only valuable in cases where your functions are very long and might throw many errors (problematic for other reasons) or if you don't have stack traces and need to piece line numbers together by hand (see above).

There are other flaws in Java's implementation, but it's been very frustrating to see how many of the new languages just reinvented Java's checked exceptions but worse instead of iterating on them.

kaapipo

I'm not even sure why we are still stuck in this debate. Isn't there quite a big consensus that the best way to handle errors is to have everything return an `Either<T, Error>` and having first-class support for monadic types?

Any design that doesn't actually force you to handle the error case cannot be called good in my opinion.

BadBadJellyBean

I stronlgy dislike Go's error handling. It is incredibly annoying to add

  if err != nil {
      <do stuff>
  }
after nearly every function call and to have a error as a secondary return type. At least for me it is clunky and annoying and incredibly distracting. If there was at least some syntactic sugar around this I could probably live with it but like this I just don't like using Go.

null

[deleted]

null

[deleted]