Go Error Handling Techniques [closed]

Your code is idiomatic and in my opinion it is the best practice available. Some would disagree for sure, but I would argue that this is the style seen all over the standard libraries in Golang. In other words, Go authors write error handling in this way.


Six months after this question was asked Rob Pike wrote a blog post titled Errors are Values.

In there he argues that you don't need to program in the way presented by the OP, and mentions several places in the standard library where they use a different pattern.

Of course a common statement involving an error value is to test whether it is nil, but there are countless other things one can do with an error value, and application of some of those other things can make your program better, eliminating much of the boilerplate that arises if every error is checked with a rote if statement.

...

Use the language to simplify your error handling.

But remember: Whatever you do, always check your errors!

It's a good read.


I would agree with jnml's answer that they are both idiomatic code, and add the following:

Your first example:

if err != nil {
      //handle err
}

is more idiomatic when dealing with more than one return value. for example:

val, err := someFunc()
if err != nil {
      //handle err
}
//do stuff with val

Your second example is nice shorthand when only dealing with the err value. This applies if the function only returns an error, or if you deliberately ignore the returned values other than the error. As an example, this is sometimes used with the Reader and Writer functions that return an int of the number of bytes written (sometimes unnecessary information) and an error:

if _, err := f.Read(file); err != nil {
      //handle err
}
//do stuff with f

The second form is referred to as using an if initialization statement.

So with regards to best practices, as far as I know (except for using the "errors" package to create new errors when you need them) you've covered pretty much everything you need to know abut errors in Go!

EDIT: If you find you really can't live without exceptions, you can mimic them with defer,panic & recover.


I made a library for streamlined error handling and piping through a queue of Go functions.

You can find it here: https://github.com/go-on/queue

It has a compact and a verbose syntactic variant. Here is an example for the short syntax:

import "github.com/go-on/queue/q"

func SaveUser(w http.ResponseWriter, rq *http.Request) {
    u := &User{}
    err := q.Q(                      
        ioutil.ReadAll, rq.Body,  // read json (returns json and error)
    )(
        // q.V pipes the json from the previous function call
        json.Unmarshal, q.V, u,   // unmarshal json from above  (returns error)
    )(
        u.Validate,               // validate the user (returns error)
    )(
        u.Save,                   // save the user (returns error)
    )(
        ok, w,                    // send the "ok" message (returns no error)
    ).Run()

    if err != nil {
       switch err {
         case *json.SyntaxError:
           ...
       }
    }
}

Please be aware that there is a little performance overhead, since it makes use of reflection.

Also this is not idiomatic go code, so you will want to use it in your own projects, or if your team agrees on using it.