github.com/thanos-io/thanos@v0.32.5/pkg/errutil/multierror.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package errutil 5 6 import ( 7 "bytes" 8 "fmt" 9 "sync" 10 ) 11 12 // The MultiError type implements the error interface, and contains the 13 // Errors used to construct it. 14 type MultiError []error 15 16 // Add adds the error to the error list if it is not nil. 17 func (es *MultiError) Add(err error) { 18 if err == nil { 19 return 20 } 21 if merr, ok := err.(NonNilMultiError); ok { 22 *es = append(*es, merr...) 23 } else { 24 *es = append(*es, err) 25 } 26 } 27 28 // Err returns the error list as an error or nil if it is empty. 29 func (es MultiError) Err() error { 30 if len(es) == 0 { 31 return nil 32 } 33 return NonNilMultiError(es) 34 } 35 36 // SyncMultiError is a thread-safe implementation of MultiError. 37 type SyncMultiError struct { 38 mtx sync.Mutex 39 es MultiError 40 } 41 42 // Add adds the error to the error list if it is not nil. 43 func (es *SyncMultiError) Add(err error) { 44 if err == nil { 45 return 46 } 47 es.mtx.Lock() 48 defer es.mtx.Unlock() 49 50 es.Add(err) 51 } 52 53 // Err returns the error list as an error or nil if it is empty. 54 func (es *SyncMultiError) Err() error { 55 es.mtx.Lock() 56 defer es.mtx.Unlock() 57 58 return es.es.Err() 59 } 60 61 type NonNilMultiError MultiError 62 63 // Returns a concatenated string of the contained errors. 64 func (es NonNilMultiError) Error() string { 65 var buf bytes.Buffer 66 67 if len(es) > 1 { 68 fmt.Fprintf(&buf, "%d errors: ", len(es)) 69 } 70 71 for i, err := range es { 72 if i != 0 { 73 buf.WriteString("; ") 74 } 75 buf.WriteString(err.Error()) 76 } 77 78 return buf.String() 79 }