From ba9669567f631efc6a0524e68222867e9cb19609 Mon Sep 17 00:00:00 2001 From: micronull <2688692+micronull@users.noreply.github.com> Date: Mon, 21 Nov 2022 16:07:01 +0500 Subject: [PATCH] fix: errors in oneOf not contain path (#676) --- openapi3/schema.go | 18 +++++-------- openapi3/schema_oneOf_test.go | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index e5cded877..dc9d0b686 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -1650,6 +1650,12 @@ type SchemaError struct { var _ interface{ Unwrap() error } = SchemaError{} func markSchemaErrorKey(err error, key string) error { + var me multiErrorForOneOf + + if errors.As(err, &me) { + err = me.Unwrap() + } + if v, ok := err.(*SchemaError); ok { v.reversePath = append(v.reversePath, key) return v @@ -1664,17 +1670,7 @@ func markSchemaErrorKey(err error, key string) error { } func markSchemaErrorIndex(err error, index int) error { - if v, ok := err.(*SchemaError); ok { - v.reversePath = append(v.reversePath, strconv.FormatInt(int64(index), 10)) - return v - } - if v, ok := err.(MultiError); ok { - for _, e := range v { - _ = markSchemaErrorIndex(e, index) - } - return v - } - return err + return markSchemaErrorKey(err, strconv.FormatInt(int64(index), 10)) } func (err *SchemaError) JSONPointer() []string { diff --git a/openapi3/schema_oneOf_test.go b/openapi3/schema_oneOf_test.go index 7faf26864..d3e689d51 100644 --- a/openapi3/schema_oneOf_test.go +++ b/openapi3/schema_oneOf_test.go @@ -3,6 +3,7 @@ package openapi3 import ( "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -134,3 +135,50 @@ func TestVisitJSON_OneOf_BadDescriminatorType(t *testing.T) { }) require.EqualError(t, err, "descriminator value is not a string") } + +func TestVisitJSON_OneOf_Path(t *testing.T) { + t.Parallel() + + loader := NewLoader() + spc := ` +components: + schemas: + Something: + type: object + properties: + first: + type: object + properties: + second: + type: object + properties: + third: + oneOf: + - title: First rule + type: string + minLength: 5 + maxLength: 5 + - title: Second rule + type: string + minLength: 10 + maxLength: 10 +`[1:] + + doc, err := loader.LoadFromData([]byte(spc)) + require.NoError(t, err) + + err = doc.Components.Schemas["Something"].Value.VisitJSON(map[string]interface{}{ + "first": map[string]interface{}{ + "second": map[string]interface{}{ + "third": "123456789", + }, + }, + }) + + assert.Contains(t, err.Error(), `Error at "/first/second/third"`) + + var sErr *SchemaError + + assert.ErrorAs(t, err, &sErr) + assert.Equal(t, []string{"first", "second", "third"}, sErr.JSONPointer()) +}