Source file src/errors/join.go

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package errors
     6  
     7  import (
     8  	"unsafe"
     9  )
    10  
    11  // Join returns an error that wraps the given errors.
    12  // Any nil error values are discarded.
    13  // Join returns nil if every value in errs is nil.
    14  // The error formats as the concatenation of the strings obtained
    15  // by calling the Error method of each element of errs, with a newline
    16  // between each string.
    17  //
    18  // A non-nil error returned by Join implements the Unwrap() []error method.
    19  func Join(errs ...error) error {
    20  	n := 0
    21  	for _, err := range errs {
    22  		if err != nil {
    23  			n++
    24  		}
    25  	}
    26  	if n == 0 {
    27  		return nil
    28  	}
    29  	if n == 1 {
    30  		for _, err := range errs {
    31  			if _, ok := err.(interface {
    32  				Unwrap() []error
    33  			}); ok {
    34  				return err
    35  			}
    36  		}
    37  	}
    38  
    39  	e := &joinError{
    40  		errs: make([]error, 0, n),
    41  	}
    42  	for _, err := range errs {
    43  		if err != nil {
    44  			e.errs = append(e.errs, err)
    45  		}
    46  	}
    47  	return e
    48  }
    49  
    50  type joinError struct {
    51  	errs []error
    52  }
    53  
    54  func (e *joinError) Error() string {
    55  	// Since Join returns nil if every value in errs is nil,
    56  	// e.errs cannot be empty.
    57  	if len(e.errs) == 1 {
    58  		return e.errs[0].Error()
    59  	}
    60  
    61  	b := []byte(e.errs[0].Error())
    62  	for _, err := range e.errs[1:] {
    63  		b = append(b, '\n')
    64  		b = append(b, err.Error()...)
    65  	}
    66  	// At this point, b has at least one byte '\n'.
    67  	return unsafe.String(&b[0], len(b))
    68  }
    69  
    70  func (e *joinError) Unwrap() []error {
    71  	return e.errs
    72  }
    73  

View as plain text