Flatten aggregated error when generating Error() string

This commit is contained in:
Jordan Liggitt 2019-01-31 09:59:02 -05:00
parent d7aee90f36
commit 6da24b591e
2 changed files with 50 additions and 3 deletions

View File

@ -71,23 +71,38 @@ func (agg aggregate) Error() string {
}
seenerrs := sets.NewString()
result := ""
for _, err := range agg {
agg.visit(func(err error) {
msg := err.Error()
if seenerrs.Has(msg) {
continue
return
}
seenerrs.Insert(msg)
if len(seenerrs) > 1 {
result += ", "
}
result += msg
}
})
if len(seenerrs) == 1 {
return result
}
return "[" + result + "]"
}
func (agg aggregate) visit(f func(err error)) {
for _, err := range agg {
switch err := err.(type) {
case aggregate:
err.visit(f)
case Aggregate:
for _, nestedErr := range err.Errors() {
f(nestedErr)
}
default:
f(err)
}
}
}
// Errors is part of the Aggregate interface.
func (agg aggregate) Errors() []error {
return []error(agg)

View File

@ -179,6 +179,38 @@ func TestDedupePluralAggregate(t *testing.T) {
}
}
func TestFlattenAndDedupeAggregate(t *testing.T) {
var slice []error = []error{fmt.Errorf("abc"), fmt.Errorf("abc"), NewAggregate([]error{fmt.Errorf("abc")})}
var agg Aggregate
agg = NewAggregate(slice)
if agg == nil {
t.Errorf("expected non-nil")
}
if s := agg.Error(); s != "abc" {
t.Errorf("expected 'abc', got %q", s)
}
if s := agg.Errors(); len(s) != 3 {
t.Errorf("expected three-elements slice, got %#v", s)
}
}
func TestFlattenAggregate(t *testing.T) {
var slice []error = []error{fmt.Errorf("abc"), fmt.Errorf("abc"), NewAggregate([]error{fmt.Errorf("abc"), fmt.Errorf("def"), NewAggregate([]error{fmt.Errorf("def"), fmt.Errorf("ghi")})})}
var agg Aggregate
agg = NewAggregate(slice)
if agg == nil {
t.Errorf("expected non-nil")
}
if s := agg.Error(); s != "[abc, def, ghi]" {
t.Errorf("expected '[abc, def, ghi]', got %q", s)
}
if s := agg.Errors(); len(s) != 3 {
t.Errorf("expected three-elements slice, got %#v", s)
}
}
func TestFilterOut(t *testing.T) {
testCases := []struct {
err error