Skip to content

Commit 409e0dc

Browse files
authored
openapi3: make bad data ... error more actionable (#761)
1 parent ac2fd9b commit 409e0dc

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

.github/workflows/go.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ jobs:
176176
Tag
177177
XML
178178
179+
- if: runner.os == 'Linux'
180+
name: Ensure readableType() covers all possible values of resolved var
181+
run: |
182+
[[ "$(git grep -F 'var resolved ' -- openapi3/loader.go | awk '{print $4}' | sort | tr '\n' ' ')" = "$RESOLVEDS" ]]
183+
env:
184+
RESOLVEDS: 'Callback CallbackRef ExampleRef HeaderRef LinkRef ParameterRef PathItem RequestBodyRef ResponseRef SchemaRef SecuritySchemeRef '
185+
179186
check-goimports:
180187
runs-on: ubuntu-latest
181188
steps:

openapi3/issue759_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package openapi3
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestIssue759(t *testing.T) {
10+
spec := []byte(`
11+
openapi: 3.0.0
12+
info:
13+
title: title
14+
description: description
15+
version: 0.0.0
16+
paths:
17+
/slash:
18+
get:
19+
responses:
20+
"200":
21+
# Ref should point to a response, not a schema
22+
$ref: "#/components/schemas/UserStruct"
23+
components:
24+
schemas:
25+
UserStruct:
26+
type: object
27+
`[1:])
28+
29+
loader := NewLoader()
30+
31+
doc, err := loader.LoadFromData(spec)
32+
require.Nil(t, doc)
33+
require.EqualError(t, err, `bad data in "#/components/schemas/UserStruct" (expecting ref to response object)`)
34+
}

openapi3/loader.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,12 +351,41 @@ func (loader *Loader) resolveComponent(doc *T, ref string, path *url.URL, resolv
351351
return nil
352352
}
353353
if err := codec(cursor, resolved); err != nil {
354-
return nil, nil, fmt.Errorf("bad data in %q", ref)
354+
return nil, nil, fmt.Errorf("bad data in %q (expecting %s)", ref, readableType(resolved))
355355
}
356356
return componentDoc, componentPath, nil
357357

358358
default:
359-
return nil, nil, fmt.Errorf("bad data in %q", ref)
359+
return nil, nil, fmt.Errorf("bad data in %q (expecting %s)", ref, readableType(resolved))
360+
}
361+
}
362+
363+
func readableType(x interface{}) string {
364+
switch x.(type) {
365+
case *Callback:
366+
return "callback object"
367+
case *CallbackRef:
368+
return "ref to callback object"
369+
case *ExampleRef:
370+
return "ref to example object"
371+
case *HeaderRef:
372+
return "ref to header object"
373+
case *LinkRef:
374+
return "ref to link object"
375+
case *ParameterRef:
376+
return "ref to parameter object"
377+
case *PathItem:
378+
return "pathItem object"
379+
case *RequestBodyRef:
380+
return "ref to requestBody object"
381+
case *ResponseRef:
382+
return "ref to response object"
383+
case *SchemaRef:
384+
return "ref to schema object"
385+
case *SecuritySchemeRef:
386+
return "ref to securityScheme object"
387+
default:
388+
panic(fmt.Sprintf("unreachable %T", x))
360389
}
361390
}
362391

0 commit comments

Comments
 (0)