In defence of Golang error handling

July, 2025

Error handling is an important part of any programming language. It is the mechanism by which we are able to capture code execution paths that are not in the happy path. In most programming languages, the concept of error handling is aptly encapsulated in the grammar as try/catch code blocks. This explicitly tells whoever is reading the code to know that the code within the try block has the potential to raise an exception or produce an error. The catch block handles errors if any occurs in the try block. This design has been the norm across many popular languages and programmers have come to expect this language design for new languages alike.

However, Golang which prides itself as an easy-to-write and lightweight systems programming language walks a different path. Golang treats errors just like values that can be returned by function calls. This design makes it explicit that every function call that returns an error has its error return value handled or ignored by choice. This design of returning error values as normal function call return values has gained Golang some negative popularity about its verbose error handling code style which makes source code to be littered with the distinct if err != nil { ... } code block.

The designers and maintainers of Golang have explored different options ([ On | No ] syntactic support for error handling) on how to reduce the verbosity of Golang's error value handling mechanism but have decided to leave the design as it is. Personally, I agree with their decision based on some convictions which I will elaborate in the ensuing paragraphs:

  1. The explicit nature of Golang's error handling makes it difficult to ignore non-happy paths in our source code. The fact that non-happy paths cannot just be ignored makes Golang a language which developers can use to write safe, secure and resilient programs.

  2. It gives programmers confidence in using external libraries that aren't well-documented or that they didn't bother to read the documentation of. Compared to other languages for example JavaScript or Kotlin, it's possible to execute a function call that has the potential to raise an exception and not handle it as a result of ignorance since these languages don't explicitly indicate in the function definition if the function call throws an exception or not.

  3. With respect to reading code, the straightforward nature of handling Golang errors makes it easy to read and understand Golang code as everything that happens within a function definition is within view which helps with understanding what is happening in a function definition.

I do agree that sometimes, Golang code can get overwhelmed with error handling sub-sections within a block of code. Nonetheless, I'm convinced that the language design of returning an error value just like any other value that would have been returned by a function call makes it easy to handle errors which results in safer programs. With this in mind, I strongly agree with the Golang language designers' decision of leaving the error value handling mechanism as is.

What do you think about Golang's error handling mechanism?