# errwrap `errwrap` is a package for Go that formalizes the pattern of wrapping errors and checking if an error contains another error. There is a common pattern in Go of taking a returned `error` value and then wrapping it (such as with `fmt.Errorf`) before returning it. The problem with this pattern is that you completely lose the original `error` structure. Arguably the _correct_ approach is that you should make a custom structure implementing the `error` interface, and have the original error as a field on that structure, such [as this example](http://golang.org/pkg/os/#PathError). This is a good approach, but you have to know the entire chain of possible rewrapping that happens, when you might just care about one. `errwrap` formalizes this pattern (it doesn't matter what approach you use above) by giving a single interface for wrapping errors, checking if a specific error is wrapped, and extracting that error. ## Installation and Docs Install using `go get github.com/hashicorp/errwrap`. Full documentation is available at http://godoc.org/github.com/hashicorp/errwrap ## Usage #### Basic Usage Below is a very basic example of its usage: ```go // A function that always returns an error, but wraps it, like a real // function might. func tryOpen() error { _, err := os.Open("/i/dont/exist") if err != nil { return errwrap.Wrapf("Doesn't exist: {{err}}", err) } return nil } func main() { err := tryOpen() // We can use the Contains helpers to check if an error contains // another error. It is safe to do this with a nil error, or with // an error that doesn't even use the errwrap package. if errwrap.Contains(err, ErrNotExist) { // Do something } if errwrap.ContainsType(err, new(os.PathError)) { // Do something } // Or we can use the associated `Get` functions to just extract // a specific error. This would return nil if that specific error doesn't // exist. perr := errwrap.GetType(err, new(os.PathError)) } ``` #### Custom Types If you're already making custom types that properly wrap errors, then you can get all the functionality of `errwraps.Contains` and such by implementing the `Wrapper` interface with just one function. Example: ```go type AppError { Code ErrorCode Err error } func (e *AppError) WrappedErrors() []error { return []error{e.Err} } ``` Now this works: ```go err := &AppError{Err: fmt.Errorf("an error")} if errwrap.ContainsType(err, fmt.Errorf("")) { // This will work! } ```