github.com/abayer/test-infra@v0.0.5/prow/errorutil/aggregate.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package errorutil
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  )
    23  
    24  // Aggregate represents an object that contains multiple errors, but does not
    25  // necessarily have singular semantic meaning.
    26  type Aggregate interface {
    27  	error
    28  	Errors() []error
    29  	Strings() []string
    30  }
    31  
    32  // NewAggregate converts a slice of errors into an Aggregate interface, which
    33  // is itself an implementation of the error interface.  If the slice is empty,
    34  // this returns nil.
    35  // It will check if any of the element of input error list is nil, to avoid
    36  // nil pointer panic when call Error().
    37  func NewAggregate(errlist ...error) Aggregate {
    38  	if len(errlist) == 0 {
    39  		return nil
    40  	}
    41  	// In case of input error list contains nil
    42  	var errs []error
    43  	for _, e := range errlist {
    44  		if e != nil {
    45  			errs = append(errs, e)
    46  		}
    47  	}
    48  	if len(errs) == 0 {
    49  		return nil
    50  	}
    51  	return aggregate(errs)
    52  }
    53  
    54  // This helper implements the error and Errors interfaces.  Keeping it private
    55  // prevents people from making an aggregate of 0 errors, which is not
    56  // an error, but does satisfy the error interface.
    57  type aggregate []error
    58  
    59  // Error is part of the error interface.
    60  func (agg aggregate) Error() string {
    61  	if len(agg) == 0 {
    62  		// This should never happen, really.
    63  		return ""
    64  	}
    65  	return fmt.Sprintf("[%s]", strings.Join(agg.Strings(), ", "))
    66  }
    67  
    68  // Strings flattens the aggregate (and any sub aggregates) into a
    69  // slice of strings.
    70  func (agg aggregate) Strings() []string {
    71  	strs := make([]string, 0, len(agg))
    72  	for _, e := range agg {
    73  		if subAgg, ok := e.(aggregate); ok {
    74  			strs = append(strs, subAgg.Strings()...)
    75  		} else {
    76  			strs = append(strs, e.Error())
    77  		}
    78  	}
    79  	return strs
    80  }
    81  
    82  // Errors is part of the Aggregate interface.
    83  func (agg aggregate) Errors() []error {
    84  	return []error(agg)
    85  }