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 }