Skip to content

Commit 34d01b0

Browse files
fix: improved handling of type validation errors and their message content
1 parent d2f8ee3 commit 34d01b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+949
-670
lines changed

arazzo/arazzo.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro
107107

108108
arazzoMajor, arazzoMinor, arazzoPatch, err := utils.ParseVersion(a.Arazzo)
109109
if err != nil {
110-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo field version is invalid %s: %s", a.Arazzo, err.Error()), core, core.Arazzo))
110+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version is invalid %s: %s", a.Arazzo, err.Error()), core, core.Arazzo))
111111
}
112112

113113
if arazzoMajor != VersionMajor || arazzoMinor != VersionMinor || arazzoPatch > VersionPatch {
114-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo field version only %s and below is supported", Version), core, core.Arazzo))
114+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version only %s and below is supported", Version), core, core.Arazzo))
115115
}
116116

117117
errs = append(errs, a.Info.Validate(ctx, opts...)...)
@@ -122,7 +122,7 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro
122122
errs = append(errs, sourceDescription.Validate(ctx, opts...)...)
123123

124124
if _, ok := sourceDescriptionNames[sourceDescription.Name]; ok {
125-
errs = append(errs, validation.NewSliceError(validation.NewValueValidationError("sourceDescription field name %s is not unique", sourceDescription.Name), core, core.SourceDescriptions, i))
125+
errs = append(errs, validation.NewSliceError(validation.NewValueValidationError("sourceDescription.name %s is not unique", sourceDescription.Name), core, core.SourceDescriptions, i))
126126
}
127127

128128
sourceDescriptionNames[sourceDescription.Name] = true
@@ -134,7 +134,7 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro
134134
errs = append(errs, workflow.Validate(ctx, opts...)...)
135135

136136
if _, ok := workflowIds[workflow.WorkflowID]; ok {
137-
errs = append(errs, validation.NewSliceError(validation.NewValueValidationError("workflow field workflowId %s is not unique", workflow.WorkflowID), core, core.Workflows, i))
137+
errs = append(errs, validation.NewSliceError(validation.NewValueValidationError("workflow.workflowId %s is not unique", workflow.WorkflowID), core, core.Workflows, i))
138138
}
139139

140140
workflowIds[workflow.WorkflowID] = true

arazzo/arazzo_examples_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,6 @@ func Example_validating() {
190190
fmt.Printf("%s\n", err.Error())
191191
}
192192
// Output:
193-
// [3:3] info field version is missing
193+
// [3:3] info.version is missing
194194
// [13:9] step at least one of operationId, operationPath or workflowId fields must be set
195195
}

arazzo/arazzo_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,11 @@ sourceDescriptions:
303303
column int
304304
underlyingError error
305305
}{
306-
{line: 1, column: 1, underlyingError: validation.NewMissingFieldError("arazzo field workflows is missing")},
307-
{line: 1, column: 9, underlyingError: validation.NewValueValidationError("arazzo field version only 1.0.1 and below is supported")},
308-
{line: 4, column: 3, underlyingError: validation.NewMissingFieldError("info field version is missing")},
309-
{line: 6, column: 5, underlyingError: validation.NewMissingFieldError("sourceDescription field url is missing")},
310-
{line: 7, column: 11, underlyingError: validation.NewValueValidationError("sourceDescription field type must be one of [openapi, arazzo]")},
306+
{line: 1, column: 1, underlyingError: validation.NewMissingFieldError("arazzo.workflows is missing")},
307+
{line: 1, column: 9, underlyingError: validation.NewValueValidationError("arazzo.version only 1.0.1 and below is supported")},
308+
{line: 4, column: 3, underlyingError: validation.NewMissingFieldError("info.version is missing")},
309+
{line: 6, column: 5, underlyingError: validation.NewMissingFieldError("sourceDescription.url is missing")},
310+
{line: 7, column: 11, underlyingError: validation.NewValueValidationError("sourceDescription.type must be one of [openapi, arazzo]")},
311311
}
312312

313313
require.Len(t, validationErrs, len(expectedErrors), "number of validation errors should match")
@@ -635,7 +635,7 @@ var stressTests = []struct {
635635
args: args{
636636
location: "https://raw.githubusercontent.com/frankkilcommins/simple-spectral-arazzo-GA/4ec8856f1cf21c0f77597c715c150ef3e2772a89/apis/OnlineStore.arazzo.yaml",
637637
validationIgnores: []string{
638-
"field title is missing", // legit issue
638+
"info.title is missing", // legit issue
639639
"operationId must be a valid expression if there are multiple OpenAPI source descriptions", // legit issue
640640
"$responses.body.menuItems[0].subcategories[0].id", // legit issue
641641
},

arazzo/components.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []
4444

4545
for key, input := range c.Inputs.All() {
4646
if !componentNameRegex.MatchString(key) {
47-
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components field inputs key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Inputs, key))
47+
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.inputs key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Inputs, key))
4848
}
4949

5050
errs = append(errs, input.Validate(ctx, opts...)...)
5151
}
5252

5353
for key, parameter := range c.Parameters.All() {
5454
if !componentNameRegex.MatchString(key) {
55-
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components field parameters key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Parameters, key))
55+
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.parameters key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Parameters, key))
5656
}
5757

5858
paramOps := opts
@@ -63,7 +63,7 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []
6363

6464
for key, successAction := range c.SuccessActions.All() {
6565
if !componentNameRegex.MatchString(key) {
66-
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components field successActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.SuccessActions, key))
66+
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.successActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.SuccessActions, key))
6767
}
6868

6969
successActionOps := opts
@@ -74,7 +74,7 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []
7474

7575
for key, failureAction := range c.FailureActions.All() {
7676
if !componentNameRegex.MatchString(key) {
77-
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components field failureActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.FailureActions, key))
77+
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.failureActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.FailureActions, key))
7878
}
7979

8080
failureActionOps := opts

arazzo/core/criterion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (c *CriterionTypeUnion) Unmarshal(ctx context.Context, parentName string, n
6363
c.DetermineValidity(validationErrs)
6464
default:
6565
return []error{
66-
validation.NewValidationError(validation.NewTypeMismatchError("criterionTypeUnion expected scalar or mapping node, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
66+
validation.NewValidationError(validation.NewTypeMismatchError(parentName, "criterionTypeUnion expected string or object, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
6767
}, nil
6868
}
6969

arazzo/core/reusable.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func (r *Reusable[T]) Unmarshal(ctx context.Context, parentName string, node *ya
3737
r.SetValid(false, false)
3838

3939
return []error{
40-
validation.NewValidationError(validation.NewTypeMismatchError("reusable expected mapping node, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
40+
validation.NewValidationError(validation.NewTypeMismatchError(parentName, "reusable expected object, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
4141
}, nil
4242
}
4343

arazzo/failureaction.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,22 @@ func (f *FailureAction) Validate(ctx context.Context, opts ...validation.Option)
6969
errs := []error{}
7070

7171
if core.Name.Present && f.Name == "" {
72-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("failureAction field name is required"), core, core.Name))
72+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("failureAction.name is required"), core, core.Name))
7373
}
7474

7575
switch f.Type {
7676
case FailureActionTypeEnd:
7777
if f.WorkflowID != nil {
78-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field workflowId is not allowed when type: end is specified"), core, core.WorkflowID))
78+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.workflowId is not allowed when type: end is specified"), core, core.WorkflowID))
7979
}
8080
if f.StepID != nil {
81-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field stepId is not allowed when type: end is specified"), core, core.StepID))
81+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.stepId is not allowed when type: end is specified"), core, core.StepID))
8282
}
8383
if f.RetryAfter != nil {
84-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field retryAfter is not allowed when type: end is specified"), core, core.RetryAfter))
84+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.retryAfter is not allowed when type: end is specified"), core, core.RetryAfter))
8585
}
8686
if f.RetryLimit != nil {
87-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field retryLimit is not allowed when type: end is specified"), core, core.RetryLimit))
87+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.retryLimit is not allowed when type: end is specified"), core, core.RetryLimit))
8888
}
8989
case FailureActionTypeGoto:
9090
workflowIDNode := core.WorkflowID.GetKeyNodeOrRoot(core.RootNode)
@@ -100,10 +100,10 @@ func (f *FailureAction) Validate(ctx context.Context, opts ...validation.Option)
100100
required: true,
101101
}, opts...)...)
102102
if f.RetryAfter != nil {
103-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field retryAfter is not allowed when type: goto is specified"), core, core.RetryAfter))
103+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.retryAfter is not allowed when type: goto is specified"), core, core.RetryAfter))
104104
}
105105
if f.RetryLimit != nil {
106-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field retryLimit is not allowed when type: goto is specified"), core, core.RetryLimit))
106+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.retryLimit is not allowed when type: goto is specified"), core, core.RetryLimit))
107107
}
108108
case FailureActionTypeRetry:
109109
workflowIDNode := core.WorkflowID.GetKeyNodeOrRoot(core.RootNode)
@@ -120,16 +120,16 @@ func (f *FailureAction) Validate(ctx context.Context, opts ...validation.Option)
120120
}, opts...)...)
121121
if f.RetryAfter != nil {
122122
if *f.RetryAfter < 0 {
123-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field retryAfter must be greater than or equal to 0"), core, core.RetryAfter))
123+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.retryAfter must be greater than or equal to 0"), core, core.RetryAfter))
124124
}
125125
}
126126
if f.RetryLimit != nil {
127127
if *f.RetryLimit < 0 {
128-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field retryLimit must be greater than or equal to 0"), core, core.RetryLimit))
128+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.retryLimit must be greater than or equal to 0"), core, core.RetryLimit))
129129
}
130130
}
131131
default:
132-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction field type must be one of [%s]", strings.Join([]string{string(FailureActionTypeEnd), string(FailureActionTypeGoto), string(FailureActionTypeRetry)}, ", ")), core, core.Type))
132+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("failureAction.type must be one of [%s]", strings.Join([]string{string(FailureActionTypeEnd), string(FailureActionTypeGoto), string(FailureActionTypeRetry)}, ", ")), core, core.Type))
133133
}
134134

135135
for i := range f.Criteria {

arazzo/info.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ func (i *Info) Validate(ctx context.Context, opts ...validation.Option) []error
3434
errs := []error{}
3535

3636
if core.Title.Present && i.Title == "" {
37-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("info field title is required"), core, core.Title))
37+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("info.title is required"), core, core.Title))
3838
}
3939

4040
if core.Version.Present && i.Version == "" {
41-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("info field version is required"), core, core.Version))
41+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("info.version is required"), core, core.Version))
4242
}
4343

4444
i.Valid = len(errs) == 0 && core.GetValid()

arazzo/parameter.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,17 @@ func (p *Parameter) Validate(ctx context.Context, opts ...validation.Option) []e
7171
default:
7272
if p.In == nil || in == "" {
7373
if w == nil && s != nil && s.WorkflowID == nil {
74-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("parameter field in is required within a step when workflowId is not set"), core, core.In))
74+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("parameter.in is required within a step when workflowId is not set"), core, core.In))
7575
}
7676
}
7777

7878
if in != "" {
79-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("parameter field in must be one of [%s] but was %s", strings.Join([]string{string(InPath), string(InQuery), string(InHeader), string(InCookie)}, ", "), in), core, core.In))
79+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("parameter.in must be one of [%s] but was %s", strings.Join([]string{string(InPath), string(InQuery), string(InHeader), string(InCookie)}, ", "), in), core, core.In))
8080
}
8181
}
8282

8383
if core.Value.Present && p.Value == nil {
84-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("parameter field value is required"), core, core.Value))
84+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("parameter.value is required"), core, core.Value))
8585
} else if p.Value != nil {
8686
_, expression, err := expression.GetValueOrExpressionValue(p.Value)
8787
if err != nil {

arazzo/payloadreplacement.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ func (p *PayloadReplacement) Validate(ctx context.Context, opts ...validation.Op
3232
errs := []error{}
3333

3434
if core.Target.Present && p.Target == "" {
35-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("payloadReplacement field target is required"), core, core.Target))
35+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("payloadReplacement.target is required"), core, core.Target))
3636
}
3737

3838
if err := p.Target.Validate(); err != nil {
39-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("payloadReplacement field target is invalid: "+err.Error()), core, core.Target))
39+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("payloadReplacement.target is invalid: "+err.Error()), core, core.Target))
4040
}
4141

4242
if core.Value.Present && p.Value == nil {
43-
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("payloadReplacement field value is required"), core, core.Value))
43+
errs = append(errs, validation.NewValueError(validation.NewMissingValueError("payloadReplacement.value is required"), core, core.Value))
4444
} else if p.Value != nil {
4545
_, expression, err := expression.GetValueOrExpressionValue(p.Value)
4646
if err != nil {
47-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("payloadReplacement field value is invalid: "+err.Error()), core, core.Value))
47+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("payloadReplacement.value is invalid: "+err.Error()), core, core.Value))
4848
}
4949
if expression != nil {
5050
if err := expression.Validate(); err != nil {
51-
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("payloadReplacement field value is invalid: "+err.Error()), core, core.Value))
51+
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("payloadReplacement.value is invalid: "+err.Error()), core, core.Value))
5252
}
5353
}
5454
}

0 commit comments

Comments
 (0)