github.com/blend/go-sdk@v1.20220411.3/ex/multi.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package ex 9 10 import ( 11 "fmt" 12 "strings" 13 ) 14 15 // Append appends errors together, creating a multi-error. 16 func Append(err error, errs ...error) error { 17 if len(errs) == 0 { 18 return err 19 } 20 var all []error 21 if err != nil { 22 all = append(all, NewWithStackDepth(err, DefaultNewStartDepth+1)) 23 } 24 for _, extra := range errs { 25 if extra != nil { 26 all = append(all, NewWithStackDepth(extra, DefaultNewStartDepth+1)) 27 } 28 } 29 if len(all) == 0 { 30 return nil 31 } 32 if len(all) == 1 { 33 return all[0] 34 } 35 return Multi(all) 36 } 37 38 // Unwrap unwraps multi-errors. 39 func Unwrap(err error) []error { 40 if typed, ok := err.(Multi); ok { 41 return []error(typed) 42 } 43 return []error{err} 44 } 45 46 // Multi represents an array of errors. 47 type Multi []error 48 49 // Error implements error. 50 func (m Multi) Error() string { 51 if len(m) == 0 { 52 return "" 53 } 54 if len(m) == 1 { 55 return fmt.Sprintf("1 error occurred:\n\t* %v\n\n", m[0]) 56 } 57 58 points := make([]string, len(m)) 59 for i, err := range m { 60 points[i] = fmt.Sprintf("* %v", err) 61 } 62 63 return fmt.Sprintf( 64 "%d errors occurred:\n\t%s\n\n", 65 len(m), strings.Join(points, "\n\t")) 66 } 67 68 // WrappedErrors implements something in errors. 69 func (m Multi) WrappedErrors() []error { 70 return m 71 } 72 73 // Unwrap returns an error from Error (or nil if there are no errors). 74 // This error returned will further support Unwrap to get the next error, 75 // etc. 76 // 77 // The resulting error supports errors.As/Is/Unwrap so you can continue 78 // to use the stdlib errors package to introspect further. 79 // 80 // This will perform a shallow copy of the errors slice. Any errors appended 81 // to this error after calling Unwrap will not be available until a new 82 // Unwrap is called on the multierror.Error. 83 func (m Multi) Unwrap() error { 84 if m == nil || len(m) == 0 { 85 return nil 86 } 87 if len(m) == 1 { 88 return m[0] 89 } 90 errs := make([]error, len(m)) 91 copy(errs, m) 92 return Nest(errs...) 93 }