• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

LICENSEH A D14-Jul-202015.6 KiB

README.mdH A D14-Jul-20202.4 KiB

errwrap.goH A D14-Jul-20204.4 KiB

errwrap_test.goH A D14-Jul-20201.8 KiB

go.modH A D14-Jul-202036

README.md

1# errwrap
2
3`errwrap` is a package for Go that formalizes the pattern of wrapping errors
4and checking if an error contains another error.
5
6There is a common pattern in Go of taking a returned `error` value and
7then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
8with this pattern is that you completely lose the original `error` structure.
9
10Arguably the _correct_ approach is that you should make a custom structure
11implementing the `error` interface, and have the original error as a field
12on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
13This is a good approach, but you have to know the entire chain of possible
14rewrapping that happens, when you might just care about one.
15
16`errwrap` formalizes this pattern (it doesn't matter what approach you use
17above) by giving a single interface for wrapping errors, checking if a specific
18error is wrapped, and extracting that error.
19
20## Installation and Docs
21
22Install using `go get github.com/hashicorp/errwrap`.
23
24Full documentation is available at
25http://godoc.org/github.com/hashicorp/errwrap
26
27## Usage
28
29#### Basic Usage
30
31Below is a very basic example of its usage:
32
33```go
34// A function that always returns an error, but wraps it, like a real
35// function might.
36func tryOpen() error {
37	_, err := os.Open("/i/dont/exist")
38	if err != nil {
39		return errwrap.Wrapf("Doesn't exist: {{err}}", err)
40	}
41
42	return nil
43}
44
45func main() {
46	err := tryOpen()
47
48	// We can use the Contains helpers to check if an error contains
49	// another error. It is safe to do this with a nil error, or with
50	// an error that doesn't even use the errwrap package.
51	if errwrap.Contains(err, "does not exist") {
52		// Do something
53	}
54	if errwrap.ContainsType(err, new(os.PathError)) {
55		// Do something
56	}
57
58	// Or we can use the associated `Get` functions to just extract
59	// a specific error. This would return nil if that specific error doesn't
60	// exist.
61	perr := errwrap.GetType(err, new(os.PathError))
62}
63```
64
65#### Custom Types
66
67If you're already making custom types that properly wrap errors, then
68you can get all the functionality of `errwraps.Contains` and such by
69implementing the `Wrapper` interface with just one function. Example:
70
71```go
72type AppError {
73  Code ErrorCode
74  Err  error
75}
76
77func (e *AppError) WrappedErrors() []error {
78  return []error{e.Err}
79}
80```
81
82Now this works:
83
84```go
85err := &AppError{Err: fmt.Errorf("an error")}
86if errwrap.ContainsType(err, fmt.Errorf("")) {
87	// This will work!
88}
89```
90