Skip to content

Commit

Permalink
openapi{2,3}: simplify unmarshal errors
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
  • Loading branch information
fenollp committed Nov 26, 2023
1 parent fe1c5f5 commit 5589aae
Show file tree
Hide file tree
Showing 32 changed files with 222 additions and 42 deletions.
26 changes: 26 additions & 0 deletions openapi2/marsh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package openapi2

import (
"encoding/json"
"fmt"
"strings"

"github.com/invopop/yaml"
)

func unmarshalError(jsonUnmarshalErr error) error {
if before, after, found := strings.Cut(jsonUnmarshalErr.Error(), "Bis."); found && before != "" && after != "" {
before = strings.ReplaceAll(before, " Go struct ", " ")
return fmt.Errorf("%s.%s", before, after)
}
return jsonUnmarshalErr
}

func unmarshal(data []byte, v interface{}) error {
// See https://github.com/getkin/kin-openapi/issues/680
if err := json.Unmarshal(data, v); err != nil {
// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys
return yaml.Unmarshal(data, v)
}
return nil
}
61 changes: 61 additions & 0 deletions openapi2/marsh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package openapi2

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestUnmarshalError(t *testing.T) {
{
v2 := []byte(`
openapi: '2.0'
info:
version: '1.10'
title: title
paths:
"/ping":
post:
consumes:
- multipart/form-data
parameters:
name: file # <-- Missing dash
in: formData
description: file
required: true
type: file
responses:
'200':
description: OK
`[1:])

var doc T
err := unmarshal(v2, &doc)
require.ErrorContains(t, err, `json: cannot unmarshal object into field Operation.parameters of type openapi2.Parameters`)
}

v2 := []byte(`
openapi: '2.0'
info:
version: '1.10'
title: title
paths:
"/ping":
post:
consumes:
- multipart/form-data
parameters:
- name: file # <--
in: formData
description: file
required: true
type: file
responses:
'200':
description: OK
`[1:])

var doc T
err := unmarshal(v2, &doc)
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion openapi2/openapi2.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (doc *T) UnmarshalJSON(data []byte) error {
type TBis T
var x TBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "swagger")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (operation *Operation) UnmarshalJSON(data []byte) error {
type OperationBis Operation
var x OperationBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "summary")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func (parameter *Parameter) UnmarshalJSON(data []byte) error {
type ParameterBis Parameter
var x ParameterBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/path_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (pathItem *PathItem) UnmarshalJSON(data []byte) error {
type PathItemBis PathItem
var x PathItemBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (response *Response) UnmarshalJSON(data []byte) error {
type ResponseBis Response
var x ResponseBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi2/security_scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (securityScheme *SecurityScheme) UnmarshalJSON(data []byte) error {
type SecuritySchemeBis SecurityScheme
var x SecuritySchemeBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (components *Components) UnmarshalJSON(data []byte) error {
type ComponentsBis Components
var x ComponentsBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "schemas")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (contact *Contact) UnmarshalJSON(data []byte) error {
type ContactBis Contact
var x ContactBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "name")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/discriminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (discriminator *Discriminator) UnmarshalJSON(data []byte) error {
type DiscriminatorBis Discriminator
var x DiscriminatorBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "propertyName")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (encoding *Encoding) UnmarshalJSON(data []byte) error {
type EncodingBis Encoding
var x EncodingBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "contentType")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (example *Example) UnmarshalJSON(data []byte) error {
type ExampleBis Example
var x ExampleBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "summary")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/external_docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (e *ExternalDocs) UnmarshalJSON(data []byte) error {
type ExternalDocsBis ExternalDocs
var x ExternalDocsBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "description")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (info *Info) UnmarshalJSON(data []byte) error {
type InfoBis Info
var x InfoBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "title")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (license *License) UnmarshalJSON(data []byte) error {
type LicenseBis License
var x LicenseBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "name")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (link *Link) UnmarshalJSON(data []byte) error {
type LinkBis Link
var x LinkBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "operationRef")
Expand Down
11 changes: 0 additions & 11 deletions openapi3/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"sort"
"strconv"
"strings"

"github.com/invopop/yaml"
)

var CircularReferenceError = "kin-openapi bug found: circular schema reference not handled"
Expand Down Expand Up @@ -178,15 +176,6 @@ func (loader *Loader) loadFromDataWithPathInternal(data []byte, location *url.UR
return doc, nil
}

func unmarshal(data []byte, v interface{}) error {
// See https://github.com/getkin/kin-openapi/issues/680
if err := json.Unmarshal(data, v); err != nil {
// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys
return yaml.Unmarshal(data, v)
}
return nil
}

// ResolveRefsIn expands references if for instance spec was just unmarshaled
func (loader *Loader) ResolveRefsIn(doc *T, location *url.URL) (err error) {
if loader.Context == nil {
Expand Down
26 changes: 26 additions & 0 deletions openapi3/marsh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package openapi3

import (
"encoding/json"
"fmt"
"strings"

"github.com/invopop/yaml"
)

func unmarshalError(jsonUnmarshalErr error) error {
if before, after, found := strings.Cut(jsonUnmarshalErr.Error(), "Bis."); found && before != "" && after != "" {
before = strings.ReplaceAll(before, " Go struct ", " ")
return fmt.Errorf("%s.%s", before, after)
}
return jsonUnmarshalErr
}

func unmarshal(data []byte, v interface{}) error {
// See https://github.com/getkin/kin-openapi/issues/680
if err := json.Unmarshal(data, v); err != nil {
// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys
return yaml.Unmarshal(data, v)
}
return nil
}
78 changes: 78 additions & 0 deletions openapi3/marsh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package openapi3

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestUnmarshalError(t *testing.T) {
{
spec := []byte(`
openapi: 3.0.1
info:
version: v1
title: Products api
components:
schemas:
someSchema:
type: object
schemaArray:
type: array
minItems: 1
items:
$ref: '#/components/schemas/someSchema'
paths:
/categories:
get:
responses:
'200':
description: ''
content:
application/json:
schema:
allOf:
$ref: '#/components/schemas/schemaArray' # <- Should have been a list
`[1:])

sl := NewLoader()

_, err := sl.LoadFromData(spec)
require.ErrorContains(t, err, `json: cannot unmarshal object into field Schema.allOf of type openapi3.SchemaRefs`)
}

spec := []byte(`
openapi: 3.0.1
info:
version: v1
title: Products api
components:
schemas:
someSchema:
type: object
schemaArray:
type: array
minItems: 1
items:
$ref: '#/components/schemas/someSchema'
paths:
/categories:
get:
responses:
'200':
description: ''
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/schemaArray' # <-
`[1:])

sl := NewLoader()

doc, err := sl.LoadFromData(spec)
require.NoError(t, err)

err = doc.Validate(sl.Context)
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion openapi3/media_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (mediaType *MediaType) UnmarshalJSON(data []byte) error {
type MediaTypeBis MediaType
var x MediaTypeBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "schema")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/openapi3.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (doc *T) UnmarshalJSON(data []byte) error {
type TBis T
var x TBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "openapi")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (operation *Operation) UnmarshalJSON(data []byte) error {
type OperationBis Operation
var x OperationBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "tags")
Expand Down
2 changes: 1 addition & 1 deletion openapi3/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (parameter *Parameter) UnmarshalJSON(data []byte) error {
type ParameterBis Parameter
var x ParameterBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)

Expand Down
2 changes: 1 addition & 1 deletion openapi3/path_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (pathItem *PathItem) UnmarshalJSON(data []byte) error {
type PathItemBis PathItem
var x PathItemBis
if err := json.Unmarshal(data, &x); err != nil {
return err
return unmarshalError(err)
}
_ = json.Unmarshal(data, &x.Extensions)
delete(x.Extensions, "$ref")
Expand Down

0 comments on commit 5589aae

Please sign in to comment.