Skip to content

Commit

Permalink
use %w to wrap the errors (#596)
Browse files Browse the repository at this point in the history
  • Loading branch information
SVilgelm authored Sep 19, 2022
1 parent 68016e0 commit d12860c
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 47 deletions.
6 changes: 3 additions & 3 deletions jsoninfo/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ObjectDecoder struct {
func NewObjectDecoder(data []byte) (*ObjectDecoder, error) {
var remainingFields map[string]json.RawMessage
if err := json.Unmarshal(data, &remainingFields); err != nil {
return nil, fmt.Errorf("failed to unmarshal extension properties: %v (%s)", err, data)
return nil, fmt.Errorf("failed to unmarshal extension properties: %w (%s)", err, data)
}
return &ObjectDecoder{
Data: data,
Expand Down Expand Up @@ -87,7 +87,7 @@ func (decoder *ObjectDecoder) DecodeStructFieldsAndExtensions(value interface{})
continue
}
}
return fmt.Errorf("failed to unmarshal property %q (%s): %v",
return fmt.Errorf("failed to unmarshal property %q (%s): %w",
field.JSONName, fieldValue.Type().String(), err)
}
if !isPtr {
Expand All @@ -109,7 +109,7 @@ func (decoder *ObjectDecoder) DecodeStructFieldsAndExtensions(value interface{})
continue
}
}
return fmt.Errorf("failed to unmarshal property %q (%s): %v",
return fmt.Errorf("failed to unmarshal property %q (%s): %w",
field.JSONName, fieldPtr.Type().String(), err)
}

Expand Down
2 changes: 1 addition & 1 deletion openapi3/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (components *Components) Validate(ctx context.Context) (err error) {
return
}
if err = v.Validate(ctx); err != nil {
return fmt.Errorf("%s: %s", k, err)
return fmt.Errorf("%s: %w", k, err)
}
}

Expand Down
8 changes: 4 additions & 4 deletions openapi3/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,22 @@ func (header *Header) Validate(ctx context.Context) error {
sm.Style == SerializationSimple && !sm.Explode ||
sm.Style == SerializationSimple && sm.Explode; !smSupported {
e := fmt.Errorf("serialization method with style=%q and explode=%v is not supported by a header parameter", sm.Style, sm.Explode)
return fmt.Errorf("header schema is invalid: %v", e)
return fmt.Errorf("header schema is invalid: %w", e)
}

if (header.Schema == nil) == (header.Content == nil) {
e := fmt.Errorf("parameter must contain exactly one of content and schema: %v", header)
return fmt.Errorf("header schema is invalid: %v", e)
return fmt.Errorf("header schema is invalid: %w", e)
}
if schema := header.Schema; schema != nil {
if err := schema.Validate(ctx); err != nil {
return fmt.Errorf("header schema is invalid: %v", err)
return fmt.Errorf("header schema is invalid: %w", err)
}
}

if content := header.Content; content != nil {
if err := content.Validate(ctx); err != nil {
return fmt.Errorf("header content is invalid: %v", err)
return fmt.Errorf("header content is invalid: %w", err)
}
}
return nil
Expand Down
8 changes: 4 additions & 4 deletions openapi3/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (loader *Loader) loadSingleElementFromURI(ref string, rootPath *url.URL, el

resolvedPath, err := resolvePath(rootPath, parsedURL)
if err != nil {
return nil, fmt.Errorf("could not resolve path: %v", err)
return nil, fmt.Errorf("could not resolve path: %w", err)
}

data, err := loader.readURL(resolvedPath)
Expand Down Expand Up @@ -285,7 +285,7 @@ func (loader *Loader) resolveComponent(

if cursor, err = drillIntoField(cursor, pathPart); err != nil {
e := failedToResolveRefFragmentPart(ref, pathPart)
return nil, fmt.Errorf("%s: %s", e.Error(), err.Error())
return nil, fmt.Errorf("%s: %w", e, err)
}
if cursor == nil {
return nil, failedToResolveRefFragmentPart(ref, pathPart)
Expand Down Expand Up @@ -430,11 +430,11 @@ func (loader *Loader) resolveRef(doc *T, ref string, path *url.URL) (*T, string,

var resolvedPath *url.URL
if resolvedPath, err = resolvePath(path, parsedURL); err != nil {
return nil, "", nil, fmt.Errorf("error resolving path: %v", err)
return nil, "", nil, fmt.Errorf("error resolving path: %w", err)
}

if doc, err = loader.loadFromURIInternal(resolvedPath); err != nil {
return nil, "", nil, fmt.Errorf("error resolving reference %q: %v", ref, err)
return nil, "", nil, fmt.Errorf("error resolving reference %q: %w", ref, err)
}

return doc, "#" + fragment, resolvedPath, nil
Expand Down
27 changes: 15 additions & 12 deletions openapi3/loader_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package openapi3

import (
"errors"
"fmt"
"net"
"net/http"
Expand Down Expand Up @@ -524,23 +523,27 @@ paths: {}
servers:
- @@@
`
for value, expected := range map[string]error{
`{url: /}`: nil,
`{url: "http://{x}.{y}.example.com"}`: errors.New("invalid servers: server has undeclared variables"),
`{url: "http://{x}.y}.example.com"}`: errors.New("invalid servers: server URL has mismatched { and }"),
`{url: "http://{x.example.com"}`: errors.New("invalid servers: server URL has mismatched { and }"),
`{url: "http://{x}.example.com", variables: {x: {default: "www"}}}`: nil,
`{url: "http://{x}.example.com", variables: {x: {default: "www", enum: ["www"]}}}`: nil,
`{url: "http://{x}.example.com", variables: {x: {enum: ["www"]}}}`: errors.New(`invalid servers: field default is required in {"enum":["www"]}`),
`{url: "http://www.example.com", variables: {x: {enum: ["www"]}}}`: errors.New("invalid servers: server has undeclared variables"),
`{url: "http://{y}.example.com", variables: {x: {enum: ["www"]}}}`: errors.New("invalid servers: server has undeclared variables"),
for value, expected := range map[string]string{
`{url: /}`: "",
`{url: "http://{x}.{y}.example.com"}`: "invalid servers: server has undeclared variables",
`{url: "http://{x}.y}.example.com"}`: "invalid servers: server URL has mismatched { and }",
`{url: "http://{x.example.com"}`: "invalid servers: server URL has mismatched { and }",
`{url: "http://{x}.example.com", variables: {x: {default: "www"}}}`: "",
`{url: "http://{x}.example.com", variables: {x: {default: "www", enum: ["www"]}}}`: "",
`{url: "http://{x}.example.com", variables: {x: {enum: ["www"]}}}`: `invalid servers: field default is required in {"enum":["www"]}`,
`{url: "http://www.example.com", variables: {x: {enum: ["www"]}}}`: "invalid servers: server has undeclared variables",
`{url: "http://{y}.example.com", variables: {x: {enum: ["www"]}}}`: "invalid servers: server has undeclared variables",
} {
t.Run(value, func(t *testing.T) {
loader := NewLoader()
doc, err := loader.LoadFromData([]byte(strings.Replace(spec, "@@@", value, 1)))
require.NoError(t, err)
err = doc.Validate(loader.Context)
require.Equal(t, expected, err)
if expected == "" {
require.NoError(t, err)
} else {
require.EqualError(t, err, expected)
}
})
}
}
4 changes: 2 additions & 2 deletions openapi3/media_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ func (mediaType *MediaType) Validate(ctx context.Context) error {
} else if examples := mediaType.Examples; examples != nil {
for k, v := range examples {
if err := v.Validate(ctx); err != nil {
return fmt.Errorf("%s: %s", k, err)
return fmt.Errorf("%s: %w", k, err)
}
if err := validateExampleValue(v.Value.Value, schema.Value); err != nil {
return fmt.Errorf("%s: %s", k, err)
return fmt.Errorf("%s: %w", k, err)
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions openapi3/openapi3.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {
// NOTE: only mention info/components/paths/... key in this func's errors.

{
wrap := func(e error) error { return fmt.Errorf("invalid components: %v", e) }
wrap := func(e error) error { return fmt.Errorf("invalid components: %w", e) }
if err := doc.Components.Validate(ctx); err != nil {
return wrap(err)
}
}

{
wrap := func(e error) error { return fmt.Errorf("invalid info: %v", e) }
wrap := func(e error) error { return fmt.Errorf("invalid info: %w", e) }
if v := doc.Info; v != nil {
if err := v.Validate(ctx); err != nil {
return wrap(err)
Expand All @@ -87,7 +87,7 @@ func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {
}

{
wrap := func(e error) error { return fmt.Errorf("invalid paths: %v", e) }
wrap := func(e error) error { return fmt.Errorf("invalid paths: %w", e) }
if v := doc.Paths; v != nil {
if err := v.Validate(ctx); err != nil {
return wrap(err)
Expand All @@ -98,7 +98,7 @@ func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {
}

{
wrap := func(e error) error { return fmt.Errorf("invalid security: %v", e) }
wrap := func(e error) error { return fmt.Errorf("invalid security: %w", e) }
if v := doc.Security; v != nil {
if err := v.Validate(ctx); err != nil {
return wrap(err)
Expand All @@ -107,7 +107,7 @@ func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {
}

{
wrap := func(e error) error { return fmt.Errorf("invalid servers: %v", e) }
wrap := func(e error) error { return fmt.Errorf("invalid servers: %w", e) }
if v := doc.Servers; v != nil {
if err := v.Validate(ctx); err != nil {
return wrap(err)
Expand Down
12 changes: 6 additions & 6 deletions openapi3/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,23 +296,23 @@ func (parameter *Parameter) Validate(ctx context.Context) error {
}
if !smSupported {
e := fmt.Errorf("serialization method with style=%q and explode=%v is not supported by a %s parameter", sm.Style, sm.Explode, in)
return fmt.Errorf("parameter %q schema is invalid: %v", parameter.Name, e)
return fmt.Errorf("parameter %q schema is invalid: %w", parameter.Name, e)
}

if (parameter.Schema == nil) == (parameter.Content == nil) {
e := errors.New("parameter must contain exactly one of content and schema")
return fmt.Errorf("parameter %q schema is invalid: %v", parameter.Name, e)
return fmt.Errorf("parameter %q schema is invalid: %w", parameter.Name, e)
}

if content := parameter.Content; content != nil {
if err := content.Validate(ctx); err != nil {
return fmt.Errorf("parameter %q content is invalid: %v", parameter.Name, err)
return fmt.Errorf("parameter %q content is invalid: %w", parameter.Name, err)
}
}

if schema := parameter.Schema; schema != nil {
if err := schema.Validate(ctx); err != nil {
return fmt.Errorf("parameter %q schema is invalid: %v", parameter.Name, err)
return fmt.Errorf("parameter %q schema is invalid: %w", parameter.Name, err)
}
if parameter.Example != nil && parameter.Examples != nil {
return fmt.Errorf("parameter %q example and examples are mutually exclusive", parameter.Name)
Expand All @@ -327,10 +327,10 @@ func (parameter *Parameter) Validate(ctx context.Context) error {
} else if examples := parameter.Examples; examples != nil {
for k, v := range examples {
if err := v.Validate(ctx); err != nil {
return fmt.Errorf("%s: %s", k, err)
return fmt.Errorf("%s: %w", k, err)
}
if err := validateExampleValue(v.Value.Value, schema.Value); err != nil {
return fmt.Errorf("%s: %s", k, err)
return fmt.Errorf("%s: %w", k, err)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion openapi3/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ func (schema *Schema) validate(ctx context.Context, stack []*Schema) (err error)

if x := schema.Example; x != nil && !validationOpts.ExamplesValidationDisabled {
if err := validateExampleValue(x, schema); err != nil {
return fmt.Errorf("invalid schema example: %s", err)
return fmt.Errorf("invalid schema example: %w", err)
}
}

Expand Down
2 changes: 1 addition & 1 deletion openapi3/schema_formats.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var SchemaStringFormats = make(map[string]Format, 4)
func DefineStringFormat(name string, pattern string) {
re, err := regexp.Compile(pattern)
if err != nil {
err := fmt.Errorf("format %q has invalid pattern %q: %v", name, pattern, err)
err := fmt.Errorf("format %q has invalid pattern %q: %w", name, pattern, err)
panic(err)
}
SchemaStringFormats[name] = Format{regexp: re}
Expand Down
2 changes: 1 addition & 1 deletion openapi3/security_scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (ss *SecurityScheme) Validate(ctx context.Context) error {
return fmt.Errorf("security scheme of type %q should have 'flows'", ss.Type)
}
if err := flow.Validate(ctx); err != nil {
return fmt.Errorf("security scheme 'flow' is invalid: %v", err)
return fmt.Errorf("security scheme 'flow' is invalid: %w", err)
}
} else if ss.Flows != nil {
return fmt.Errorf("security scheme of type %q can't have 'flows'", ss.Type)
Expand Down
12 changes: 6 additions & 6 deletions openapi3filter/req_resp_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ func (d *cookieParamDecoder) DecodePrimitive(param string, sm *openapi3.Serializ
return nil, found, nil
}
if err != nil {
return nil, found, fmt.Errorf("decoding param %q: %s", param, err)
return nil, found, fmt.Errorf("decoding param %q: %w", param, err)
}

val, err := parsePrimitive(cookie.Value, schema)
Expand All @@ -673,7 +673,7 @@ func (d *cookieParamDecoder) DecodeArray(param string, sm *openapi3.Serializatio
return nil, found, nil
}
if err != nil {
return nil, found, fmt.Errorf("decoding param %q: %s", param, err)
return nil, found, fmt.Errorf("decoding param %q: %w", param, err)
}
val, err := parseArray(strings.Split(cookie.Value, ","), schema)
return val, found, err
Expand All @@ -691,7 +691,7 @@ func (d *cookieParamDecoder) DecodeObject(param string, sm *openapi3.Serializati
return nil, found, nil
}
if err != nil {
return nil, found, fmt.Errorf("decoding param %q: %s", param, err)
return nil, found, fmt.Errorf("decoding param %q: %w", param, err)
}
props, err := propsFromString(cookie.Value, ",", ",")
if err != nil {
Expand Down Expand Up @@ -753,7 +753,7 @@ func makeObject(props map[string]string, schema *openapi3.SchemaRef) (map[string
if v, ok := err.(*ParseError); ok {
return nil, &ParseError{path: []interface{}{propName}, Cause: v}
}
return nil, fmt.Errorf("property %q: %s", propName, err)
return nil, fmt.Errorf("property %q: %w", propName, err)
}
obj[propName] = value
}
Expand All @@ -771,7 +771,7 @@ func parseArray(raw []string, schemaRef *openapi3.SchemaRef) ([]interface{}, err
if v, ok := err.(*ParseError); ok {
return nil, &ParseError{path: []interface{}{i}, Cause: v}
}
return nil, fmt.Errorf("item %d: %s", i, err)
return nil, fmt.Errorf("item %d: %w", i, err)
}

// If the items are nil, then the array is nil. There shouldn't be case where some values are actual primitive
Expand Down Expand Up @@ -1044,7 +1044,7 @@ func multipartBodyDecoder(body io.Reader, header http.Header, schema *openapi3.S
if v, ok := err.(*ParseError); ok {
return nil, &ParseError{path: []interface{}{name}, Cause: v}
}
return nil, fmt.Errorf("part %s: %s", name, err)
return nil, fmt.Errorf("part %s: %w", name, err)
}
values[name] = append(values[name], value)
}
Expand Down
2 changes: 1 addition & 1 deletion routers/legacy/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type Router struct {
// All operations of the document will be added to the router.
func NewRouter(doc *openapi3.T) (routers.Router, error) {
if err := doc.Validate(context.Background()); err != nil {
return nil, fmt.Errorf("validating OpenAPI failed: %v", err)
return nil, fmt.Errorf("validating OpenAPI failed: %w", err)
}
router := &Router{doc: doc}
root := router.node()
Expand Down

0 comments on commit d12860c

Please sign in to comment.