From fe08dc2e56cda3381264063be40fb164d8081baa Mon Sep 17 00:00:00 2001 From: Daniel Castro Date: Sat, 24 Sep 2022 15:32:54 +0000 Subject: [PATCH 1/2] initial commit --- openapi3/components.go | 8 ++++---- openapi3/example_validation_test.go | 16 ++++++++-------- openapi3/issue601_test.go | 2 +- openapi3/media_type.go | 6 +++--- openapi3/parameter.go | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/openapi3/components.go b/openapi3/components.go index 3f883faf0..a4d60b529 100644 --- a/openapi3/components.go +++ b/openapi3/components.go @@ -49,10 +49,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range schemas { v := components.Schemas[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("%s: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("%s: %w", k, err) } } @@ -139,10 +139,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range examples { v := components.Examples[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("example %s: %w", k, err) } if err = v.Validate(ctx); err != nil { - return fmt.Errorf("%s: %w", k, err) + return fmt.Errorf("example %s: %w", k, err) } } diff --git a/openapi3/example_validation_test.go b/openapi3/example_validation_test.go index 177360c13..bf3ff2be1 100644 --- a/openapi3/example_validation_test.go +++ b/openapi3/example_validation_test.go @@ -41,7 +41,7 @@ func TestExamplesSchemaValidation(t *testing.T) { parametersExample: ` example: abcd `, - errContains: "invalid paths", + errContains: "invalid path /user: invalid operation POST: invalid example", }, { name: "valid_parameter_example", @@ -64,7 +64,7 @@ func TestExamplesSchemaValidation(t *testing.T) { email: bad password: short `, - errContains: "invalid paths: invalid path /user: invalid operation POST: BadUser", + errContains: "invalid paths: invalid path /user: invalid operation POST: example BadUser", }, { name: "valid_component_examples", @@ -90,7 +90,7 @@ func TestExamplesSchemaValidation(t *testing.T) { email: bad password: short `, - errContains: "invalid paths", + errContains: "invalid path /user: invalid operation POST: invalid example", }, { name: "valid_mediatype_examples", @@ -109,7 +109,7 @@ func TestExamplesSchemaValidation(t *testing.T) { email: good@email.com # missing password `, - errContains: "invalid schema example", + errContains: "CreateUserRequest: invalid schema example", }, { name: "valid_schema_request_example", @@ -127,7 +127,7 @@ func TestExamplesSchemaValidation(t *testing.T) { user_id: 1 # missing access_token `, - errContains: "invalid schema example", + errContains: "CreateUserResponse: invalid schema example", }, { name: "valid_schema_response_example", @@ -278,7 +278,7 @@ func TestExampleObjectValidation(t *testing.T) { email: real@email.com password: validpassword `, - errContains: "example and examples are mutually exclusive", + errContains: "invalid path /user: invalid operation POST: example and examples are mutually exclusive", componentExamples: ` examples: BadUser: @@ -295,7 +295,7 @@ func TestExampleObjectValidation(t *testing.T) { BadUser: description: empty user example `, - errContains: "example has no value or externalValue field", + errContains: "invalid components: example BadUser: example has no value or externalValue field", }, { name: "value_externalValue_mutual_exclusion", @@ -308,7 +308,7 @@ func TestExampleObjectValidation(t *testing.T) { password: validpassword externalValue: 'http://example.com/examples/example' `, - errContains: "value and externalValue are mutually exclusive", + errContains: "invalid components: example BadUser: value and externalValue are mutually exclusive", }, } diff --git a/openapi3/issue601_test.go b/openapi3/issue601_test.go index 420ac9dc2..4ca6bec01 100644 --- a/openapi3/issue601_test.go +++ b/openapi3/issue601_test.go @@ -18,7 +18,7 @@ func TestIssue601(t *testing.T) { require.NoError(t, err) err = doc.Validate(sl.Context) - require.Contains(t, err.Error(), `invalid components: invalid schema example: Error at "/type": property "type" is missing`) + require.Contains(t, err.Error(), `invalid components: DiscoveryResult: invalid schema example: Error at "/type": property "type" is missing`) require.Contains(t, err.Error(), `| Error at "/nsid": property "nsid" is missing`) err = doc.Validate(sl.Context, DisableExamplesValidation()) diff --git a/openapi3/media_type.go b/openapi3/media_type.go index 4269a4e64..1ae7c996a 100644 --- a/openapi3/media_type.go +++ b/openapi3/media_type.go @@ -94,7 +94,7 @@ func (mediaType *MediaType) Validate(ctx context.Context) error { if example := mediaType.Example; example != nil { if err := validateExampleValue(example, schema.Value); err != nil { - return err + return fmt.Errorf("invalid example: %w", err) } } @@ -107,10 +107,10 @@ func (mediaType *MediaType) Validate(ctx context.Context) error { for _, k := range names { v := examples[k] if err := v.Validate(ctx); err != nil { - return fmt.Errorf("%s: %w", k, err) + return fmt.Errorf("example %s: %w", k, err) } if err := validateExampleValue(v.Value.Value, schema.Value); err != nil { - return fmt.Errorf("%s: %w", k, err) + return fmt.Errorf("example %s: %w", k, err) } } } diff --git a/openapi3/parameter.go b/openapi3/parameter.go index 6e2dbca08..73a39a54f 100644 --- a/openapi3/parameter.go +++ b/openapi3/parameter.go @@ -323,7 +323,7 @@ func (parameter *Parameter) Validate(ctx context.Context) error { } if example := parameter.Example; example != nil { if err := validateExampleValue(example, schema.Value); err != nil { - return err + return fmt.Errorf("invalid example: %w", err) } } else if examples := parameter.Examples; examples != nil { names := make([]string, 0, len(examples)) From ba9c64164566a4003a942ceb9ee0a530a74df4b9 Mon Sep 17 00:00:00 2001 From: Daniel Castro Date: Mon, 26 Sep 2022 15:55:21 +0000 Subject: [PATCH 2/2] specific errors for components fields --- openapi3/components.go | 36 ++++++++++++++--------------- openapi3/example.go | 2 +- openapi3/example_validation_test.go | 8 +++---- openapi3/issue601_test.go | 2 +- openapi3/schema.go | 4 ++-- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/openapi3/components.go b/openapi3/components.go index a4d60b529..b7ad11c80 100644 --- a/openapi3/components.go +++ b/openapi3/components.go @@ -49,10 +49,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range schemas { v := components.Schemas[k] if err = ValidateIdentifier(k); err != nil { - return fmt.Errorf("%s: %w", k, err) + return fmt.Errorf("schema %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return fmt.Errorf("%s: %w", k, err) + return fmt.Errorf("schema %q: %w", k, err) } } @@ -64,10 +64,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range parameters { v := components.Parameters[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("parameter %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("parameter %q: %w", k, err) } } @@ -79,10 +79,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range requestBodies { v := components.RequestBodies[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("request body %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("request body %q: %w", k, err) } } @@ -94,10 +94,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range responses { v := components.Responses[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("response %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("response %q: %w", k, err) } } @@ -109,10 +109,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range headers { v := components.Headers[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("header %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("header %q: %w", k, err) } } @@ -124,10 +124,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range securitySchemes { v := components.SecuritySchemes[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("security scheme %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("security scheme %q: %w", k, err) } } @@ -139,10 +139,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range examples { v := components.Examples[k] if err = ValidateIdentifier(k); err != nil { - return fmt.Errorf("example %s: %w", k, err) + return fmt.Errorf("example %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return fmt.Errorf("example %s: %w", k, err) + return fmt.Errorf("example %q: %w", k, err) } } @@ -154,10 +154,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range links { v := components.Links[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("link %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("link %q: %w", k, err) } } @@ -169,10 +169,10 @@ func (components *Components) Validate(ctx context.Context) (err error) { for _, k := range callbacks { v := components.Callbacks[k] if err = ValidateIdentifier(k); err != nil { - return + return fmt.Errorf("callback %q: %w", k, err) } if err = v.Validate(ctx); err != nil { - return + return fmt.Errorf("callback %q: %w", k, err) } } diff --git a/openapi3/example.go b/openapi3/example.go index e63c78fa6..2161b688b 100644 --- a/openapi3/example.go +++ b/openapi3/example.go @@ -60,7 +60,7 @@ func (example *Example) Validate(ctx context.Context) error { return errors.New("value and externalValue are mutually exclusive") } if example.Value == nil && example.ExternalValue == "" { - return errors.New("example has no value or externalValue field") + return errors.New("no value or externalValue field") } return nil diff --git a/openapi3/example_validation_test.go b/openapi3/example_validation_test.go index bf3ff2be1..f6a495ace 100644 --- a/openapi3/example_validation_test.go +++ b/openapi3/example_validation_test.go @@ -109,7 +109,7 @@ func TestExamplesSchemaValidation(t *testing.T) { email: good@email.com # missing password `, - errContains: "CreateUserRequest: invalid schema example", + errContains: "schema \"CreateUserRequest\": invalid example", }, { name: "valid_schema_request_example", @@ -127,7 +127,7 @@ func TestExamplesSchemaValidation(t *testing.T) { user_id: 1 # missing access_token `, - errContains: "CreateUserResponse: invalid schema example", + errContains: "schema \"CreateUserResponse\": invalid example", }, { name: "valid_schema_response_example", @@ -295,7 +295,7 @@ func TestExampleObjectValidation(t *testing.T) { BadUser: description: empty user example `, - errContains: "invalid components: example BadUser: example has no value or externalValue field", + errContains: "invalid components: example \"BadUser\": no value or externalValue field", }, { name: "value_externalValue_mutual_exclusion", @@ -308,7 +308,7 @@ func TestExampleObjectValidation(t *testing.T) { password: validpassword externalValue: 'http://example.com/examples/example' `, - errContains: "invalid components: example BadUser: value and externalValue are mutually exclusive", + errContains: "invalid components: example \"BadUser\": value and externalValue are mutually exclusive", }, } diff --git a/openapi3/issue601_test.go b/openapi3/issue601_test.go index 4ca6bec01..ef841c25f 100644 --- a/openapi3/issue601_test.go +++ b/openapi3/issue601_test.go @@ -18,7 +18,7 @@ func TestIssue601(t *testing.T) { require.NoError(t, err) err = doc.Validate(sl.Context) - require.Contains(t, err.Error(), `invalid components: DiscoveryResult: invalid schema example: Error at "/type": property "type" is missing`) + require.Contains(t, err.Error(), `invalid components: schema "DiscoveryResult": invalid example: Error at "/type": property "type" is missing`) require.Contains(t, err.Error(), `| Error at "/nsid": property "nsid" is missing`) err = doc.Validate(sl.Context, DisableExamplesValidation()) diff --git a/openapi3/schema.go b/openapi3/schema.go index e9b6617fe..641ce8507 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -763,13 +763,13 @@ func (schema *Schema) validate(ctx context.Context, stack []*Schema) (err error) if v := schema.Default; v != nil { if err := schema.VisitJSON(v); err != nil { - return fmt.Errorf("invalid schema default: %w", err) + return fmt.Errorf("invalid default: %w", err) } } if x := schema.Example; x != nil && !validationOpts.ExamplesValidationDisabled { if err := validateExampleValue(x, schema); err != nil { - return fmt.Errorf("invalid schema example: %w", err) + return fmt.Errorf("invalid example: %w", err) } }