Skip to content

Commit 38a1748

Browse files
authored
Handle compilation error (#205)
Instead of setting `CompilationError`s found in the build process on the mesasge evaluator, this sets them on their respective field evaluators. They are then returned when the field is evaluated. This ensures that all constraints ae built, even when a `CompilationError` is encountered. This makes the `Filter` API easier to use because then all constraints are built, and then `CompilationError`s are returned during the evaluation layer. The main change is that `CompilationError`s are no longer "fail fast" immediately, and instead allow for all constraints to be built and cached. Fixes #204
1 parent 9a3f1e9 commit 38a1748

File tree

7 files changed

+636
-6
lines changed

7 files changed

+636
-6
lines changed

buf.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ lint:
1212
PROTOVALIDATE:
1313
- proto/tests/example/v1/validations.proto
1414
- proto/tests/example/v1/filter.proto
15+
- proto/tests/example/v1/compile.proto
1516
breaking:
1617
use:
1718
- FILE

builder.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,7 @@ func (bldr *builder) buildMessage(
139139
}
140140

141141
for _, step := range steps {
142-
if step(desc, msgConstraints, msgEval, cache); msgEval.Err != nil {
143-
break
144-
}
142+
step(desc, msgConstraints, msgEval, cache)
145143
}
146144
}
147145

@@ -200,8 +198,7 @@ func (bldr *builder) processFields(
200198
fieldConstraints := resolve.FieldConstraints(fdesc)
201199
fldEval, err := bldr.buildField(fdesc, fieldConstraints, cache)
202200
if err != nil {
203-
msgEval.Err = err
204-
return
201+
fldEval.Err = err
205202
}
206203
msgEval.AppendNested(fldEval)
207204
}

field.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ type field struct {
4646
IgnoreDefault bool
4747
// Zero is the default or zero-value for this value's type
4848
Zero protoreflect.Value
49+
// Err stores if there was a compilation error constructing this evaluator. It is stored
50+
// here so that it can be returned as part of validating this specific field.
51+
Err error
4952
}
5053

5154
func (f field) Evaluate(_ protoreflect.Message, val protoreflect.Value, cfg *validationConfig) error {
@@ -57,6 +60,10 @@ func (f field) EvaluateMessage(msg protoreflect.Message, cfg *validationConfig)
5760
return nil
5861
}
5962

63+
if f.Err != nil {
64+
return f.Err
65+
}
66+
6067
if f.Required && !msg.Has(f.Value.Descriptor) {
6168
return &ValidationError{Violations: []*Violation{{
6269
Proto: &validate.Violation{
@@ -84,7 +91,7 @@ func (f field) EvaluateMessage(msg protoreflect.Message, cfg *validationConfig)
8491
}
8592

8693
func (f field) Tautology() bool {
87-
return !f.Required && f.Value.Tautology()
94+
return !f.Required && f.Value.Tautology() && f.Err == nil
8895
}
8996

9097
var _ messageEvaluator = field{}

internal/gen/tests/example/v1/compile.pb.go

Lines changed: 261 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)