github.com/jmigpin/editor@v1.6.0/util/iout/multierror.go (about)

     1  package iout
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"sync"
     7  )
     8  
     9  type MultiError struct {
    10  	errors []error
    11  	addMu  sync.Mutex
    12  }
    13  
    14  // Returns an error (MultiError) or nil if the errors added were all nil.
    15  func MultiErrors(errs ...error) error {
    16  	me := &MultiError{}
    17  	for _, e := range errs {
    18  		me.Add(e)
    19  	}
    20  	return me.Result()
    21  }
    22  
    23  // Returns itself, or nil if it has no errors.
    24  func (me *MultiError) Result() error {
    25  	if len(me.errors) == 0 {
    26  		return nil
    27  	}
    28  	return me
    29  }
    30  
    31  // Can be used concurrently.
    32  func (me *MultiError) Add(err error) {
    33  	if err != nil {
    34  		me.addMu.Lock()
    35  		me.errors = append(me.errors, err)
    36  		me.addMu.Unlock()
    37  	}
    38  }
    39  
    40  func (me *MultiError) Error() string {
    41  	if len(me.errors) == 1 {
    42  		return me.errors[0].Error()
    43  	}
    44  	u := []string{}
    45  	for i, e := range me.errors {
    46  		v := indentNewlines("\t", e.Error())
    47  		u = append(u, fmt.Sprintf("err%d: %v", i+1, v))
    48  	}
    49  	v := "\t" + indentNewlines("\t", strings.Join(u, "\n"))
    50  	return fmt.Sprintf("multierror(%d){\n%s\n}", len(me.errors), v)
    51  }
    52  
    53  func indentNewlines(tab string, u string) string {
    54  	u = strings.ReplaceAll(u, "\n", "\n"+tab)
    55  	return u
    56  }