Repository: getkin/kin-openapi
Pull request #605 (2022-09-20 03:26:25)

Improve error message when path validation fails
With the introduction of validation of examples in an OpenAPI spec in #592 there is now a high chance that many will have specs that fail validation. I did! It was hard to debug what was wrong with the spec as the errors were too generic. The change in this PR will hopefully make it easier for folks to debug the problem in their OpenAPI docs.

praneetloke: Hmm I looked at the failing tests and tried to update them. But something funky is going on with the unmarshal code. It seems that the value receiver method `Validate` is losing the value for the string properties in the struct somehow. Is this because it's a value receiver instead of a [pointer receiver](https://go.dev/tour/methods/4)? Basically, `Summary` is always blank in the `Validate` method for a `PathItem` and so is `Description` even when I update the test OpenAPI JSON docs that are in each of those tests. I do see the value in those properties just before I enter the `Validate` method. That's when it loses them.

Patch:
diff --git a/openapi3/path_item.go b/openapi3/path_item.go
index 4801e5f..940b159 100644
--- a/openapi3/path_item.go
+++ b/openapi3/path_item.go
@@ -134,7 +134,7 @@ func (pathItem *PathItem) Validate(ctx context.Context) error {
 	for _, method := range methods {
 		operation := operations[method]
 		if err := operation.Validate(ctx); err != nil {
-			return err
+			return fmt.Errorf("invalid operation %s: %v", method, err)
 		}
 	}
 	return nil
diff --git a/openapi3/paths.go b/openapi3/paths.go
index b116f6c..e3da7d0 100644
--- a/openapi3/paths.go
+++ b/openapi3/paths.go
@@ -96,7 +96,7 @@ func (paths Paths) Validate(ctx context.Context) error {
 		}
 
 		if err := pathItem.Validate(ctx); err != nil {
-			return err
+			return fmt.Errorf("invalid path %s: %v", path, err)
 		}
 	}
 


Test patch:
diff --git a/openapi3/example_validation_test.go b/openapi3/example_validation_test.go
index 85e158e..177360c 100644
--- a/openapi3/example_validation_test.go
+++ b/openapi3/example_validation_test.go
@@ -26,7 +26,7 @@ func TestExamplesSchemaValidation(t *testing.T) {
             param1example:
               value: abcd
    `,
-			errContains: "invalid paths: param1example",
+			errContains: "invalid paths: invalid path /user: invalid operation POST: param1example",
 		},
 		{
 			name: "valid_parameter_examples",
@@ -64,7 +64,7 @@ func TestExamplesSchemaValidation(t *testing.T) {
         email: bad
         password: short
    `,
-			errContains: "invalid paths: BadUser",
+			errContains: "invalid paths: invalid path /user: invalid operation POST: BadUser",
 		},
 		{
 			name: "valid_component_examples",
diff --git a/openapi3/loader_test.go b/openapi3/loader_test.go
index 64a923c..d492e24 100644
--- a/openapi3/loader_test.go
+++ b/openapi3/loader_test.go
@@ -96,7 +96,7 @@ func TestResolveSchemaRefWithNullSchemaRef(t *testing.T) {
 	doc, err := loader.LoadFromData(source)
 	require.NoError(t, err)
 	err = doc.Validate(loader.Context)
-	require.EqualError(t, err, `invalid paths: found unresolved ref: ""`)
+	require.EqualError(t, err, `invalid paths: invalid path /foo: invalid operation POST: found unresolved ref: ""`)
 }
 
 func TestResolveResponseExampleRef(t *testing.T) {
diff --git a/openapi3/response_issue224_test.go b/openapi3/response_issue224_test.go
index 97c7e6b..5de0525 100644
--- a/openapi3/response_issue224_test.go
+++ b/openapi3/response_issue224_test.go
@@ -457,5 +457,5 @@ func TestEmptyResponsesAreInvalid(t *testing.T) {
 	require.NoError(t, err)
 	require.Equal(t, doc.ExternalDocs.Description, "See AsyncAPI example")
 	err = doc.Validate(context.Background())
-	require.EqualError(t, err, `invalid paths: the responses object MUST contain at least one response code`)
+	require.EqualError(t, err, `invalid paths: invalid path /pet: invalid operation POST: the responses object MUST contain at least one response code`)
 }