...

Source file src/sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/errors/errors.go

Documentation: sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/errors

     1  // Code generated by k8scopy from k8s.io/apimachinery@v0.19.8; DO NOT EDIT.
     2  // File content copied from k8s.io/apimachinery@v0.19.8/pkg/util/errors/errors.go
     3  
     4  /*
     5  Copyright 2015 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package errors
    21  
    22  import (
    23  	"errors"
    24  	"fmt"
    25  
    26  	"sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/sets"
    27  )
    28  
    29  // MessageCountMap contains occurrence for each error message.
    30  type MessageCountMap map[string]int
    31  
    32  // Aggregate represents an object that contains multiple errors, but does not
    33  // necessarily have singular semantic meaning.
    34  // The aggregate can be used with `errors.Is()` to check for the occurrence of
    35  // a specific error type.
    36  // Errors.As() is not supported, because the caller presumably cares about a
    37  // specific error of potentially multiple that match the given type.
    38  type Aggregate interface {
    39  	error
    40  	Errors() []error
    41  	Is(error) bool
    42  }
    43  
    44  // NewAggregate converts a slice of errors into an Aggregate interface, which
    45  // is itself an implementation of the error interface.  If the slice is empty,
    46  // this returns nil.
    47  // It will check if any of the element of input error list is nil, to avoid
    48  // nil pointer panic when call Error().
    49  func NewAggregate(errlist []error) Aggregate {
    50  	if len(errlist) == 0 {
    51  		return nil
    52  	}
    53  	// In case of input error list contains nil
    54  	var errs []error
    55  	for _, e := range errlist {
    56  		if e != nil {
    57  			errs = append(errs, e)
    58  		}
    59  	}
    60  	if len(errs) == 0 {
    61  		return nil
    62  	}
    63  	return aggregate(errs)
    64  }
    65  
    66  // This helper implements the error and Errors interfaces.  Keeping it private
    67  // prevents people from making an aggregate of 0 errors, which is not
    68  // an error, but does satisfy the error interface.
    69  type aggregate []error
    70  
    71  // Error is part of the error interface.
    72  func (agg aggregate) Error() string {
    73  	if len(agg) == 0 {
    74  		// This should never happen, really.
    75  		return ""
    76  	}
    77  	if len(agg) == 1 {
    78  		return agg[0].Error()
    79  	}
    80  	seenerrs := sets.NewString()
    81  	result := ""
    82  	agg.visit(func(err error) bool {
    83  		msg := err.Error()
    84  		if seenerrs.Has(msg) {
    85  			return false
    86  		}
    87  		seenerrs.Insert(msg)
    88  		if len(seenerrs) > 1 {
    89  			result += ", "
    90  		}
    91  		result += msg
    92  		return false
    93  	})
    94  	if len(seenerrs) == 1 {
    95  		return result
    96  	}
    97  	return "[" + result + "]"
    98  }
    99  
   100  func (agg aggregate) Is(target error) bool {
   101  	return agg.visit(func(err error) bool {
   102  		return errors.Is(err, target)
   103  	})
   104  }
   105  
   106  func (agg aggregate) visit(f func(err error) bool) bool {
   107  	for _, err := range agg {
   108  		switch err := err.(type) {
   109  		case aggregate:
   110  			if match := err.visit(f); match {
   111  				return match
   112  			}
   113  		case Aggregate:
   114  			for _, nestedErr := range err.Errors() {
   115  				if match := f(nestedErr); match {
   116  					return match
   117  				}
   118  			}
   119  		default:
   120  			if match := f(err); match {
   121  				return match
   122  			}
   123  		}
   124  	}
   125  
   126  	return false
   127  }
   128  
   129  // Errors is part of the Aggregate interface.
   130  func (agg aggregate) Errors() []error {
   131  	return []error(agg)
   132  }
   133  
   134  // Matcher is used to match errors.  Returns true if the error matches.
   135  type Matcher func(error) bool
   136  
   137  // FilterOut removes all errors that match any of the matchers from the input
   138  // error.  If the input is a singular error, only that error is tested.  If the
   139  // input implements the Aggregate interface, the list of errors will be
   140  // processed recursively.
   141  //
   142  // This can be used, for example, to remove known-OK errors (such as io.EOF or
   143  // os.PathNotFound) from a list of errors.
   144  func FilterOut(err error, fns ...Matcher) error {
   145  	if err == nil {
   146  		return nil
   147  	}
   148  	if agg, ok := err.(Aggregate); ok {
   149  		return NewAggregate(filterErrors(agg.Errors(), fns...))
   150  	}
   151  	if !matchesError(err, fns...) {
   152  		return err
   153  	}
   154  	return nil
   155  }
   156  
   157  // matchesError returns true if any Matcher returns true
   158  func matchesError(err error, fns ...Matcher) bool {
   159  	for _, fn := range fns {
   160  		if fn(err) {
   161  			return true
   162  		}
   163  	}
   164  	return false
   165  }
   166  
   167  // filterErrors returns any errors (or nested errors, if the list contains
   168  // nested Errors) for which all fns return false. If no errors
   169  // remain a nil list is returned. The resulting silec will have all
   170  // nested slices flattened as a side effect.
   171  func filterErrors(list []error, fns ...Matcher) []error {
   172  	result := []error{}
   173  	for _, err := range list {
   174  		r := FilterOut(err, fns...)
   175  		if r != nil {
   176  			result = append(result, r)
   177  		}
   178  	}
   179  	return result
   180  }
   181  
   182  // Flatten takes an Aggregate, which may hold other Aggregates in arbitrary
   183  // nesting, and flattens them all into a single Aggregate, recursively.
   184  func Flatten(agg Aggregate) Aggregate {
   185  	result := []error{}
   186  	if agg == nil {
   187  		return nil
   188  	}
   189  	for _, err := range agg.Errors() {
   190  		if a, ok := err.(Aggregate); ok {
   191  			r := Flatten(a)
   192  			if r != nil {
   193  				result = append(result, r.Errors()...)
   194  			}
   195  		} else {
   196  			if err != nil {
   197  				result = append(result, err)
   198  			}
   199  		}
   200  	}
   201  	return NewAggregate(result)
   202  }
   203  
   204  // CreateAggregateFromMessageCountMap converts MessageCountMap Aggregate
   205  func CreateAggregateFromMessageCountMap(m MessageCountMap) Aggregate {
   206  	if m == nil {
   207  		return nil
   208  	}
   209  	result := make([]error, 0, len(m))
   210  	for errStr, count := range m {
   211  		var countStr string
   212  		if count > 1 {
   213  			countStr = fmt.Sprintf(" (repeated %v times)", count)
   214  		}
   215  		result = append(result, fmt.Errorf("%v%v", errStr, countStr))
   216  	}
   217  	return NewAggregate(result)
   218  }
   219  
   220  // Reduce will return err or, if err is an Aggregate and only has one item,
   221  // the first item in the aggregate.
   222  func Reduce(err error) error {
   223  	if agg, ok := err.(Aggregate); ok && err != nil {
   224  		switch len(agg.Errors()) {
   225  		case 1:
   226  			return agg.Errors()[0]
   227  		case 0:
   228  			return nil
   229  		}
   230  	}
   231  	return err
   232  }
   233  
   234  // AggregateGoroutines runs the provided functions in parallel, stuffing all
   235  // non-nil errors into the returned Aggregate.
   236  // Returns nil if all the functions complete successfully.
   237  func AggregateGoroutines(funcs ...func() error) Aggregate {
   238  	errChan := make(chan error, len(funcs))
   239  	for _, f := range funcs {
   240  		go func(f func() error) { errChan <- f() }(f)
   241  	}
   242  	errs := make([]error, 0)
   243  	for i := 0; i < cap(errChan); i++ {
   244  		if err := <-errChan; err != nil {
   245  			errs = append(errs, err)
   246  		}
   247  	}
   248  	return NewAggregate(errs)
   249  }
   250  
   251  // ErrPreconditionViolated is returned when the precondition is violated
   252  var ErrPreconditionViolated = errors.New("precondition is violated")
   253  

View as plain text