go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/utils/multierr/errors.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package multierr
     5  
     6  import (
     7  	"strconv"
     8  	"strings"
     9  )
    10  
    11  // withMessage and methods are taken frmo https://github.com/pkg/errors
    12  // under BSD-2-Clause license
    13  
    14  type withMessage struct {
    15  	cause error
    16  	msg   string
    17  }
    18  
    19  func (w withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
    20  func (w withMessage) Cause() error  { return w.cause }
    21  
    22  func Wrap(err error, message string) error {
    23  	if err == nil {
    24  		return nil
    25  	}
    26  	return withMessage{
    27  		cause: err,
    28  		msg:   message,
    29  	}
    30  }
    31  
    32  type Errors struct {
    33  	errors []error
    34  }
    35  
    36  func (m *Errors) Add(err ...error) {
    37  	for i := range err {
    38  		if err[i] != nil {
    39  			m.errors = append(m.errors, err[i])
    40  		}
    41  	}
    42  }
    43  
    44  func (m *Errors) Error() string {
    45  	var res strings.Builder
    46  
    47  	n := strconv.Itoa(len(m.errors))
    48  	if n == "1" {
    49  		res.WriteString("1 error occurred:\n")
    50  	} else {
    51  		res.WriteString(n + " errors occured:\n")
    52  	}
    53  
    54  	for i := range m.errors {
    55  		res.WriteString("\t* ")
    56  		res.WriteString(m.errors[i].Error())
    57  		res.WriteByte('\n')
    58  	}
    59  	return res.String()
    60  }
    61  
    62  func (m Errors) Deduplicate() error {
    63  	if len(m.errors) == 0 {
    64  		return nil
    65  	}
    66  
    67  	track := map[string]error{}
    68  	for i := range m.errors {
    69  		e := m.errors[i]
    70  		track[e.Error()] = e
    71  	}
    72  
    73  	res := make([]error, len(track))
    74  	i := 0
    75  	for _, v := range track {
    76  		res[i] = v
    77  		i++
    78  	}
    79  	return &Errors{errors: res}
    80  }
    81  
    82  func (m Errors) IsEmpty() bool {
    83  	return len(m.errors) == 0
    84  }