85 lines
1.5 KiB
Go
85 lines
1.5 KiB
Go
package errs
|
|
|
|
import (
|
|
"log/slog"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type Multi []error
|
|
|
|
func (mu Multi) LogValue() slog.Value {
|
|
vals := make([]slog.Attr, len(mu))
|
|
for i, e := range mu {
|
|
vals[i] = slog.Any(strconv.Itoa(i+1), e)
|
|
}
|
|
return slog.GroupValue(vals...)
|
|
}
|
|
|
|
func (mu Multi) Error() string {
|
|
s := strings.Builder{}
|
|
for i, err := range mu.Clean() {
|
|
if i > 0 {
|
|
s.WriteString("; ")
|
|
}
|
|
s.WriteString(strconv.Itoa(i + 1))
|
|
s.WriteString(". ")
|
|
s.WriteString(err.Error())
|
|
}
|
|
return s.String()
|
|
}
|
|
|
|
func (mu Multi) Clean() Multi {
|
|
out := make(Multi, 0, len(mu))
|
|
for _, err := range mu {
|
|
if err != nil {
|
|
out = append(out, err)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func (mu Multi) Resolve() error {
|
|
out := mu.Clean()
|
|
if len(out) == 0 {
|
|
return nil
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Close closes multiple close functions in go routines
|
|
// and returns all that errors in the order they are defined.
|
|
//
|
|
// All errors that are nil will be discarded from the list.
|
|
//
|
|
// If no errors met, Close returns nil.
|
|
func Close(funcs ...func() error) error {
|
|
if len(funcs) == 0 {
|
|
return nil
|
|
}
|
|
errs := make(Multi, len(funcs))
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(len(funcs))
|
|
for i, fn := range funcs {
|
|
go func(i int, fn func() error) {
|
|
defer wg.Done()
|
|
errs[i] = fn()
|
|
}(i, fn)
|
|
}
|
|
wg.Wait()
|
|
return errs.Resolve()
|
|
}
|
|
|
|
// Join joins the error into one error.
|
|
//
|
|
// Join discards errors that are nil.
|
|
//
|
|
// If all errs are nil, Join returns nil.
|
|
func Join(errs ...error) error {
|
|
if len(errs) == 0 {
|
|
return nil
|
|
}
|
|
return Multi(errs).Resolve()
|
|
}
|