Problem: You want to reduce the number of lines of repetitive error - handling code.
Solution: Use helper functions to reduce the number of lines of repetitive error - handling code.
One of the most frequent complaints about Go’s error handling, especially from newcomers, is that it’s tedious to do repetitive checks. Let’s take, for example, this piece of code that opens a JSON file to read and unmarshal to a struct:
func unmarshal () ( person Person ) { r , err := http . Get ( "https://swapi.dev/api/people/1" ) if err != nil { // handle error } defer r . Body . Close () data , err := io . ReadAll ( r . Body ) if err != nil { // handle error } err = json . Unmarshal ( data , & person ) if err != nil { // handle error } return person }
You can see three sets of error handling: one when you call http.Get to get the API response into an http.Response , then when you call io.ReadAll to get the JSON text from the http.Response , and finally to unmarshal the JSON text into the Person struct. Each of these calls is a potential point of failure, so you need to handle errors that result from those failures.
However, these error - handling routines are similar to each other and, in fact, repetitive. How can you resolve this? There are several ways, but the most straightforward is using helper functions:
func helperUnmarshal () ( person Person ) { r , err := http . Get ( "https://swapi.dev/api/people/1" ) check ( err , "Calling SW people API" ) defer r . Body . Close () data , err := io . ReadAll ( r . Body ) check ( err , "Read JSON from response" ) err = json . Unmarshal ( data , & person ) check ( err , "Unmarshalling" ) return person } func check ( err error , msg string ) { if err != nil { log . Println ( "Error encountered:" , msg ) // do common error - handling stuff } }
The helper function here is the check function that takes in an error and a string. Besides logging the string, you can also put all the common error - handling stuff that you want to do into the function. Instead of a string, you can also take in a function as a parameter and execute the function if an error is encountered.