...

Text file src/github.com/hashicorp/go-multierror/README.md

Documentation: github.com/hashicorp/go-multierror

     1# go-multierror
     2
     3[![CircleCI](https://img.shields.io/circleci/build/github/hashicorp/go-multierror/master)](https://circleci.com/gh/hashicorp/go-multierror)
     4[![Go Reference](https://pkg.go.dev/badge/github.com/hashicorp/go-multierror.svg)](https://pkg.go.dev/github.com/hashicorp/go-multierror)
     5![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/hashicorp/go-multierror)
     6
     7[circleci]: https://app.circleci.com/pipelines/github/hashicorp/go-multierror
     8[godocs]: https://pkg.go.dev/github.com/hashicorp/go-multierror
     9
    10`go-multierror` is a package for Go that provides a mechanism for
    11representing a list of `error` values as a single `error`.
    12
    13This allows a function in Go to return an `error` that might actually
    14be a list of errors. If the caller knows this, they can unwrap the
    15list and access the errors. If the caller doesn't know, the error
    16formats to a nice human-readable format.
    17
    18`go-multierror` is fully compatible with the Go standard library
    19[errors](https://golang.org/pkg/errors/) package, including the
    20functions `As`, `Is`, and `Unwrap`. This provides a standardized approach
    21for introspecting on error values.
    22
    23## Installation and Docs
    24
    25Install using `go get github.com/hashicorp/go-multierror`.
    26
    27Full documentation is available at
    28https://pkg.go.dev/github.com/hashicorp/go-multierror
    29
    30### Requires go version 1.13 or newer
    31
    32`go-multierror` requires go version 1.13 or newer. Go 1.13 introduced
    33[error wrapping](https://golang.org/doc/go1.13#error_wrapping), which
    34this library takes advantage of.
    35
    36If you need to use an earlier version of go, you can use the
    37[v1.0.0](https://github.com/hashicorp/go-multierror/tree/v1.0.0)
    38tag, which doesn't rely on features in go 1.13.
    39
    40If you see compile errors that look like the below, it's likely that
    41you're on an older version of go:
    42
    43```
    44/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As
    45/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is
    46```
    47
    48## Usage
    49
    50go-multierror is easy to use and purposely built to be unobtrusive in
    51existing Go applications/libraries that may not be aware of it.
    52
    53**Building a list of errors**
    54
    55The `Append` function is used to create a list of errors. This function
    56behaves a lot like the Go built-in `append` function: it doesn't matter
    57if the first argument is nil, a `multierror.Error`, or any other `error`,
    58the function behaves as you would expect.
    59
    60```go
    61var result error
    62
    63if err := step1(); err != nil {
    64	result = multierror.Append(result, err)
    65}
    66if err := step2(); err != nil {
    67	result = multierror.Append(result, err)
    68}
    69
    70return result
    71```
    72
    73**Customizing the formatting of the errors**
    74
    75By specifying a custom `ErrorFormat`, you can customize the format
    76of the `Error() string` function:
    77
    78```go
    79var result *multierror.Error
    80
    81// ... accumulate errors here, maybe using Append
    82
    83if result != nil {
    84	result.ErrorFormat = func([]error) string {
    85		return "errors!"
    86	}
    87}
    88```
    89
    90**Accessing the list of errors**
    91
    92`multierror.Error` implements `error` so if the caller doesn't know about
    93multierror, it will work just fine. But if you're aware a multierror might
    94be returned, you can use type switches to access the list of errors:
    95
    96```go
    97if err := something(); err != nil {
    98	if merr, ok := err.(*multierror.Error); ok {
    99		// Use merr.Errors
   100	}
   101}
   102```
   103
   104You can also use the standard [`errors.Unwrap`](https://golang.org/pkg/errors/#Unwrap)
   105function. This will continue to unwrap into subsequent errors until none exist.
   106
   107**Extracting an error**
   108
   109The standard library [`errors.As`](https://golang.org/pkg/errors/#As)
   110function can be used directly with a multierror to extract a specific error:
   111
   112```go
   113// Assume err is a multierror value
   114err := somefunc()
   115
   116// We want to know if "err" has a "RichErrorType" in it and extract it.
   117var errRich RichErrorType
   118if errors.As(err, &errRich) {
   119	// It has it, and now errRich is populated.
   120}
   121```
   122
   123**Checking for an exact error value**
   124
   125Some errors are returned as exact errors such as the [`ErrNotExist`](https://golang.org/pkg/os/#pkg-variables)
   126error in the `os` package. You can check if this error is present by using
   127the standard [`errors.Is`](https://golang.org/pkg/errors/#Is) function.
   128
   129```go
   130// Assume err is a multierror value
   131err := somefunc()
   132if errors.Is(err, os.ErrNotExist) {
   133	// err contains os.ErrNotExist
   134}
   135```
   136
   137**Returning a multierror only if there are errors**
   138
   139If you build a `multierror.Error`, you can use the `ErrorOrNil` function
   140to return an `error` implementation only if there are errors to return:
   141
   142```go
   143var result *multierror.Error
   144
   145// ... accumulate errors here
   146
   147// Return the `error` only if errors were added to the multierror, otherwise
   148// return nil since there are no errors.
   149return result.ErrorOrNil()
   150```

View as plain text