Skip to content

Commit 009936b

Browse files
author
Antoine Pelisse
committed
Change the way we aggregate path for errors
1 parent 9731b8f commit 009936b

File tree

4 files changed

+35
-22
lines changed

4 files changed

+35
-22
lines changed

typed/helpers.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,32 @@ func (errs ValidationErrors) WithPath(p string) ValidationErrors {
6464
return errs
6565
}
6666

67-
// Prefix all errors path with the given pathelement. This is useful
68-
// when unwinding the stack on errors.
67+
// WithPrefix prefixes all errors path with the given pathelement. This
68+
// is useful when unwinding the stack on errors.
6969
func (errs ValidationErrors) WithPrefix(prefix string) ValidationErrors {
7070
for i := range errs {
7171
errs[i].Path = prefix + errs[i].Path
7272
}
7373
return errs
7474
}
7575

76+
// WithLazyPrefix prefixes all errors path with the given pathelement.
77+
// This is useful when unwinding the stack on errors. Prefix is
78+
// computed lazily only if there is an error.
79+
func (errs ValidationErrors) WithLazyPrefix(fn func() string) ValidationErrors {
80+
if len(errs) == 0 {
81+
return errs
82+
}
83+
prefix := ""
84+
if fn != nil {
85+
prefix = fn()
86+
}
87+
for i := range errs {
88+
errs[i].Path = prefix + errs[i].Path
89+
}
90+
return errs
91+
}
92+
7693
func errorf(format string, args ...interface{}) ValidationErrors {
7794
return ValidationErrors{{
7895
ErrorMessage: fmt.Sprintf(format, args...),

typed/merge.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ var (
6868
)
6969

7070
// merge sets w.out.
71-
func (w *mergingWalker) merge() (errs ValidationErrors) {
71+
func (w *mergingWalker) merge(prefixFn func() string) (errs ValidationErrors) {
7272
if w.lhs == nil && w.rhs == nil {
7373
// check this condidition here instead of everywhere below.
7474
return errorf("at least one of lhs and rhs must be provided")
@@ -91,7 +91,7 @@ func (w *mergingWalker) merge() (errs ValidationErrors) {
9191
if !w.inLeaf && w.postItemHook != nil {
9292
w.postItemHook(w)
9393
}
94-
return errs
94+
return errs.WithLazyPrefix(prefixFn)
9595
}
9696

9797
// doLeaf should be called on leaves before descending into children, if there
@@ -223,9 +223,8 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
223223
if rchild, ok := observedRHS.Get(pe); ok {
224224
w2.rhs = rchild
225225
}
226-
if newErrs := w2.merge(); len(newErrs) > 0 {
227-
errs = append(errs, newErrs.WithPrefix(pe.String())...)
228-
} else if w2.out != nil {
226+
errs = append(errs, w2.merge(pe.String)...)
227+
if w2.out != nil {
229228
out = append(out, *w2.out)
230229
}
231230
w.finishDescent(w2)
@@ -239,9 +238,8 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
239238
value, _ := observedRHS.Get(pe)
240239
w2 := w.prepareDescent(pe, t.ElementType)
241240
w2.rhs = value
242-
if newErrs := w2.merge(); len(newErrs) > 0 {
243-
errs = append(errs, newErrs.WithPrefix(pe.String())...)
244-
} else if w2.out != nil {
241+
errs = append(errs, w2.merge(pe.String)...)
242+
if w2.out != nil {
245243
out = append(out, *w2.out)
246244
}
247245
w.finishDescent(w2)
@@ -302,13 +300,12 @@ func (w *mergingWalker) visitMapItem(t *schema.Map, out map[string]interface{},
302300
w2 := w.prepareDescent(pe, fieldType)
303301
w2.lhs = lhs
304302
w2.rhs = rhs
305-
if newErrs := w2.merge(); len(newErrs) > 0 {
306-
errs = append(errs, newErrs.WithPrefix(pe.String())...)
307-
} else if w2.out != nil {
303+
errs = append(errs, w2.merge(pe.String)...)
304+
if w2.out != nil {
308305
out[key] = *w2.out
309306
}
310307
w.finishDescent(w2)
311-
return nil
308+
return errs
312309
}
313310

314311
func (w *mergingWalker) visitMapItems(t *schema.Map, lhs, rhs value.Map) (errs ValidationErrors) {

typed/typed.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (tv TypedValue) AsValue() value.Value {
7070
func (tv TypedValue) Validate() error {
7171
w := tv.walker()
7272
defer w.finished()
73-
if errs := w.validate(); len(errs) != 0 {
73+
if errs := w.validate(nil); len(errs) != 0 {
7474
return errs
7575
}
7676
return nil
@@ -239,7 +239,7 @@ func merge(lhs, rhs *TypedValue, rule, postRule mergeRule) (*TypedValue, error)
239239
mw.rule = rule
240240
mw.postItemHook = postRule
241241

242-
errs := mw.merge()
242+
errs := mw.merge(nil)
243243
if len(errs) > 0 {
244244
return nil, errs
245245
}

typed/validate.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ func (v *validatingObjectWalker) finishDescent(v2 *validatingObjectWalker) {
7373
*v.spareWalkers = append(*v.spareWalkers, v2)
7474
}
7575

76-
func (v *validatingObjectWalker) validate() ValidationErrors {
77-
return resolveSchema(v.schema, v.typeRef, v.value, v)
76+
func (v *validatingObjectWalker) validate(prefixFn func() string) ValidationErrors {
77+
return resolveSchema(v.schema, v.typeRef, v.value, v).WithLazyPrefix(prefixFn)
7878
}
7979

8080
func validateScalar(t *schema.Scalar, v value.Value, prefix string) (errs ValidationErrors) {
@@ -133,9 +133,7 @@ func (v *validatingObjectWalker) visitListItems(t *schema.List, list value.List)
133133
}
134134
v2 := v.prepareDescent(t.ElementType)
135135
v2.value = child
136-
if newErrs := v2.validate(); len(newErrs) != 0 {
137-
errs = append(errs, newErrs.WithPrefix(pe.String())...)
138-
}
136+
errs = append(errs, v2.validate(pe.String)...)
139137
v.finishDescent(v2)
140138
}
141139
return errs
@@ -168,7 +166,8 @@ func (v *validatingObjectWalker) visitMapItems(t *schema.Map, m value.Map) (errs
168166
}
169167
v2 := v.prepareDescent(tr)
170168
v2.value = val
171-
errs = append(errs, v2.validate()...)
169+
// Giving pe.String as a parameter actually increases the allocations.
170+
errs = append(errs, v2.validate(func() string { return pe.String() })...)
172171
v.finishDescent(v2)
173172
return true
174173
})

0 commit comments

Comments
 (0)