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 err != nil {
    32  				if _, ok := err.(interface {
    33  					Unwrap() []error
    34  				}); ok {
    35  					return err
    36  				}
    37  			}
    38  		}
    39  	}
    40  
    41  	e := &joinError{
    42  		errs: make([]error, 0, n),
    43  	}
    44  	for _, err := range errs {
    45  		if err != nil {
    46  			e.errs = append(e.errs, err)
    47  		}
    48  	}
    49  	return e
    50  }
    51  
    52  type joinError struct {
    53  	errs []error
    54  }
    55  
    56  func (e *joinError) Error() string {
    57  	// Since Join returns nil if every value in errs is nil,
    58  	// e.errs cannot be empty.
    59  	if len(e.errs) == 1 {
    60  		return e.errs[0].Error()
    61  	}
    62  
    63  	b := []byte(e.errs[0].Error())
    64  	for _, err := range e.errs[1:] {
    65  		b = append(b, '\n')
    66  		b = append(b, err.Error()...)
    67  	}
    68  	// At this point, b has at least one byte '\n'.
    69  	return unsafe.String(&b[0], len(b))
    70  }
    71  
    72  func (e *joinError) Unwrap() []error {
    73  	return e.errs
    74  }
    75  

View as plain text