Skip to content

Commit

Permalink
Fix panics on invalid Node ID args (#185)
Browse files Browse the repository at this point in the history
* Fix panics on invalid Node ID args
* Add path to internal gateway resolver errors
  • Loading branch information
JohnStarich authored Mar 10, 2023
1 parent 98a598a commit c26b382
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
go-version: ^1.18
go-version: 1.18.x # Avoid latest here. New Go versions can break linters.
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
Expand Down
16 changes: 14 additions & 2 deletions gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gateway

import (
"context"
"encoding/json"
"errors"
"fmt"
"strings"
Expand Down Expand Up @@ -311,8 +312,19 @@ func makeNodeField() *QueryField {
},
},
Resolver: func(ctx context.Context, args map[string]interface{}) (string, error) {
// pass it to the user
return args["id"].(string), nil
id := args["id"]
if id == nil {
return "", fmt.Errorf("argument 'id' is required")
}
idStr, ok := id.(string)
if !ok {
jsonID, err := json.Marshal(id)
if err != nil {
return "", fmt.Errorf("invalid ID type")
}
return "", fmt.Errorf("invalid ID type: %s", string(jsonID))
}
return idStr, nil
},
}
}
Expand Down
5 changes: 4 additions & 1 deletion internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ func (g *Gateway) Query(ctx context.Context, input *graphql.QueryInput, receiver
// find the id of the entity
id, err := qField.Resolver(ctx, args)
if err != nil {
return err
return &graphql.Error{
Message: err.Error(),
Path: []interface{}{field.Alias},
}
}

// assign the id to the response
Expand Down
124 changes: 124 additions & 0 deletions internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,127 @@ func TestSchema_resolveNodeIDFromArg(t *testing.T) {
ID string `json:"id"`
}{ID: "my-id"}}, result)
}

func TestSchema_resolveNodeWrongIDType(t *testing.T) {
t.Parallel()
type Node struct {
ID *string `json:"id"`
}
type Result struct {
Node Node `json:"node"`
}
var result Result

query := `
{
node(id: 123) {
id
}
}
`

err := schemaTestLoadQuery(query, result, map[string]interface{}{})
assert.Equal(t, graphql.ErrorList{
&graphql.Error{
Message: "invalid ID type: 123",
Path: []interface{}{"node"},
},
}, err)
assert.Equal(t, Result{
Node: Node{ID: nil},
}, result)
}

func TestSchema_resolveNodeMissingIDArg(t *testing.T) {
t.Parallel()
type Node struct {
ID *string `json:"id"`
}
type Result struct {
Node Node `json:"node"`
}
var result Result

query := `
query ($id: ID!) {
node(id: $id) {
id
}
}
`
variables := map[string]interface{}{} // missing ID arg

err := schemaTestLoadQuery(query, result, variables)
assert.Equal(t, graphql.ErrorList{
&graphql.Error{
Message: "argument 'id' is required",
Path: []interface{}{"node"},
},
}, err)
assert.Equal(t, Result{
Node: Node{ID: nil},
}, result)
}

func TestSchema_resolveNodeWrongIDArgType(t *testing.T) {
t.Parallel()
type Node struct {
ID *string `json:"id"`
}
type Result struct {
Node Node `json:"node"`
}
var result Result

query := `
query ($id: ID!) {
node(id: $id) {
id
}
}
`
variables := map[string]interface{}{
"id": 123,
}

err := schemaTestLoadQuery(query, result, variables)
assert.Equal(t, graphql.ErrorList{
&graphql.Error{
Message: "invalid ID type: 123",
Path: []interface{}{"node"},
},
}, err)
assert.Equal(t, Result{
Node: Node{ID: nil},
}, result)
}

func TestSchema_resolveNodeWrongIDTypeWithAlias(t *testing.T) {
t.Parallel()
type Node struct {
ID *string `json:"id"`
}
type Result struct {
Node Node `json:"node"`
}
var result Result

query := `
{
myAlias: node(id: 123) {
id
}
}
`

err := schemaTestLoadQuery(query, result, map[string]interface{}{})
assert.Equal(t, graphql.ErrorList{
&graphql.Error{
Message: "invalid ID type: 123",
Path: []interface{}{"myAlias"},
},
}, err)
assert.Equal(t, Result{
Node: Node{ID: nil},
}, result)
}

0 comments on commit c26b382

Please sign in to comment.