...

Source file src/github.com/hashicorp/go-multierror/multierror.go

Documentation: github.com/hashicorp/go-multierror

     1  package multierror
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  // Error is an error type to track multiple errors. This is used to
     9  // accumulate errors in cases and return them as a single "error".
    10  type Error struct {
    11  	Errors      []error
    12  	ErrorFormat ErrorFormatFunc
    13  }
    14  
    15  func (e *Error) Error() string {
    16  	fn := e.ErrorFormat
    17  	if fn == nil {
    18  		fn = ListFormatFunc
    19  	}
    20  
    21  	return fn(e.Errors)
    22  }
    23  
    24  // ErrorOrNil returns an error interface if this Error represents
    25  // a list of errors, or returns nil if the list of errors is empty. This
    26  // function is useful at the end of accumulation to make sure that the value
    27  // returned represents the existence of errors.
    28  func (e *Error) ErrorOrNil() error {
    29  	if e == nil {
    30  		return nil
    31  	}
    32  	if len(e.Errors) == 0 {
    33  		return nil
    34  	}
    35  
    36  	return e
    37  }
    38  
    39  func (e *Error) GoString() string {
    40  	return fmt.Sprintf("*%#v", *e)
    41  }
    42  
    43  // WrappedErrors returns the list of errors that this Error is wrapping. It is
    44  // an implementation of the errwrap.Wrapper interface so that multierror.Error
    45  // can be used with that library.
    46  //
    47  // This method is not safe to be called concurrently. Unlike accessing the
    48  // Errors field directly, this function also checks if the multierror is nil to
    49  // prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface.
    50  func (e *Error) WrappedErrors() []error {
    51  	if e == nil {
    52  		return nil
    53  	}
    54  	return e.Errors
    55  }
    56  
    57  // Unwrap returns an error from Error (or nil if there are no errors).
    58  // This error returned will further support Unwrap to get the next error,
    59  // etc. The order will match the order of Errors in the multierror.Error
    60  // at the time of calling.
    61  //
    62  // The resulting error supports errors.As/Is/Unwrap so you can continue
    63  // to use the stdlib errors package to introspect further.
    64  //
    65  // This will perform a shallow copy of the errors slice. Any errors appended
    66  // to this error after calling Unwrap will not be available until a new
    67  // Unwrap is called on the multierror.Error.
    68  func (e *Error) Unwrap() error {
    69  	// If we have no errors then we do nothing
    70  	if e == nil || len(e.Errors) == 0 {
    71  		return nil
    72  	}
    73  
    74  	// If we have exactly one error, we can just return that directly.
    75  	if len(e.Errors) == 1 {
    76  		return e.Errors[0]
    77  	}
    78  
    79  	// Shallow copy the slice
    80  	errs := make([]error, len(e.Errors))
    81  	copy(errs, e.Errors)
    82  	return chain(errs)
    83  }
    84  
    85  // chain implements the interfaces necessary for errors.Is/As/Unwrap to
    86  // work in a deterministic way with multierror. A chain tracks a list of
    87  // errors while accounting for the current represented error. This lets
    88  // Is/As be meaningful.
    89  //
    90  // Unwrap returns the next error. In the cleanest form, Unwrap would return
    91  // the wrapped error here but we can't do that if we want to properly
    92  // get access to all the errors. Instead, users are recommended to use
    93  // Is/As to get the correct error type out.
    94  //
    95  // Precondition: []error is non-empty (len > 0)
    96  type chain []error
    97  
    98  // Error implements the error interface
    99  func (e chain) Error() string {
   100  	return e[0].Error()
   101  }
   102  
   103  // Unwrap implements errors.Unwrap by returning the next error in the
   104  // chain or nil if there are no more errors.
   105  func (e chain) Unwrap() error {
   106  	if len(e) == 1 {
   107  		return nil
   108  	}
   109  
   110  	return e[1:]
   111  }
   112  
   113  // As implements errors.As by attempting to map to the current value.
   114  func (e chain) As(target interface{}) bool {
   115  	return errors.As(e[0], target)
   116  }
   117  
   118  // Is implements errors.Is by comparing the current value directly.
   119  func (e chain) Is(target error) bool {
   120  	return errors.Is(e[0], target)
   121  }
   122  

View as plain text