UPDATE for Go 1.20:
As of Go version 1.20 you can join errors with the new errors.Join function (nil errors are ignored):
err = errors.Join(err, nil, err2, err3)
Playground Example for errors.Join
Also, the fmt.Errorf function now supports wrapping multiple errors with multiple %w format verbs:
err := fmt.Errorf("%w; %w; %w", err, err2, err3)
Playground Example for fmt.Errorf
UPDATE for Go 1.13:
As of Go version 1.13, the language's errors package now supports error wrapping directly.
You can wrap an error by using the %w verb in fmt.Errorf:
err := errors.New("Original error")
err = fmt.Errorf("%w; Second error", err)
Use Unwrap to remove the last error added, and return what remains: previousErrors := errors.Unwrap(err)
Playground Example for errors.Unwrap
Two more functions, errors.Is and errors.As provide ways to check for and retrieve a specific type of error.
Playground Example for errors.As and errors.Is
Dave Cheney's excellent errors package (https://github.com/pkg/errors) include a Wrap function for this purpose:
package main
import "fmt"
import "github.com/pkg/errors"
func main() {
err := errors.New("error")
err = errors.Wrap(err, "open failed")
err = errors.Wrap(err, "read config failed")
fmt.Println(err) // "read config failed: open failed: error"
}
This also allows additional functionality, such as unpacking the cause of the error:
package main
import "fmt"
import "github.com/pkg/errors"
func main() {
err := errors.New("original error")
err = errors.Wrap(err, "now this")
fmt.Println(errors.Cause(err)) // "original error"
}
As well as the option to output a stack trace when specifying fmt.Printf("%+v\n", err).
You can find additional information about the package on his blog: here and here.