Skip to content

oneof schema error improvment  #289

@shaj13

Description

@shaj13

Context:
currently, the library when validating an input against a schema and when an error occurred it returns schema error contains scheme filed where the error happens or input is invalid, under some circumstance, this is still not a piece of useful information to exactly know what happened behind the scene.

Pain:
Inappropriate error message returned when input matches more than "oneof" scheme.

Goal:
return a different error to distinguish input match more than oneof schemas (conflict) from input does not match oneof schemas.

Got:
Error at "/address": Doesn't match schema "oneOf"

Expected:
Error at "/address": Conflict input match all oneof schemas"

Reproduce:

package main

import (
	"fmt"

	"github.com/getkin/kin-openapi/openapi3"
)

func main() {
	data := map[string]interface{}{
		"name":      "kin-openapi",
		"address": "127.0.0.1",
	}
	s, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData([]byte(api))
	if err != nil {
		panic(err)
	}
	err = s.Components.Schemas["Server"].Value.VisitJSON(data)
	fmt.Println(err)

	//
}

var api = 
`components: 
  schemas: 
    Server: 
      properties: 
        address: 
          oneOf: 
            - $ref: "#/components/schemas/ip-address"
            - $ref: "#/components/schemas/domain-name"
        name: 
          type: string
      type: object
    domain-name: 
      maxLength: 10
      minLength: 5
      pattern: "((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)|\\."
      type: string
    ip-address: 
      pattern: "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"
      type: string
openapi: "3.0.1"
`

Note:

Suggested Solution:

var ErrOneOfConflict = errors.new("input match all oneof schemas")  

//  https://github.com/getkin/kin-openapi/blob/master/openapi3/schema.go#L850.
		if ok != 1 {
			if settings.failfast {
				return errSchema
			}
			 err := &SchemaError{
				Value:       value,
				Schema:      schema,
				SchemaField: "oneOf",
			}
                        if ok > 1 {
                           err.Origin = ErrOneOfConflict
                         }
                        return err 
		}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions