mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-16 08:10:02 +00:00
961c878e0d
Switch to using Go modules. This migrates our vendor.json to use Go 1.11's modules system, and replaces the vendor folder with the output of go mod vendor. The vendored code should remain basically the same; I believe some tree shaking of packages and support scripts/licenses/READMEs/etc. happened. This also fixes Travis and our Makefile to no longer use govendor.
90 lines
2.4 KiB
Markdown
90 lines
2.4 KiB
Markdown
# 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, "does not exist") {
|
|
// 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!
|
|
}
|
|
```
|