Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

panic when decoding null element in enum list from a query variable #922

Closed
jszwedko opened this issue Nov 6, 2019 · 2 comments · Fixed by #923
Closed

panic when decoding null element in enum list from a query variable #922

jszwedko opened this issue Nov 6, 2019 · 2 comments · Fixed by #923

Comments

@jszwedko
Copy link

jszwedko commented Nov 6, 2019

What happened?

A panic occurs when attempting to pass a null value from a query variable that maps to a GraphQL list that can contain null elements (e.g. with an enum Status, the input is [Status]).

Notably this only happens when the query arguments are passed separately as variables and not when they are passed inline with the graphql document.

I.e.

query Todos($status: [Status]) {
  todos(status: $status) {
    id
  }
}

With query arguments:

{
    "status": [null]
}

panics, but:

query Todos {
  todos(status: [null]) {
    id
  }
}

does not.

Panic stacktrace:

2019/11/06 15:42:33 http: panic serving [::1]:41834: reflect: call of reflect.Value.Type on zero Value
goroutine 25 [running]:
net/http.(*conn).serve.func1(0xc0000a3180)
        /usr/local/go/src/net/http/server.go:1767 +0x139
panic(0x8184c0, 0xc0002607a0)
        /usr/local/go/src/runtime/panic.go:679 +0x1b2
reflect.Value.Type(0x0, 0x0, 0x0, 0x6, 0xc00006bb98)
        /usr/local/go/src/reflect/value.go:1877 +0x166
github.com/vektah/gqlparser/validator.(*varValidator).validateVarType(0xc0001777a0, 0xc000278090, 0x0, 0x0, 0x0, 0x0)
        /home/jesse/go/pkg/mod/github.com/vektah/[email protected]/validator/vars.go:114 +0x13f1
github.com/vektah/gqlparser/validator.(*varValidator).validateVarType(0xc0001777a0, 0xc000278060, 0x7ef900, 0xc000260400, 0x97, 0x0)
        /home/jesse/go/pkg/mod/github.com/vektah/[email protected]/validator/vars.go:99 +0x17ec
github.com/vektah/gqlparser/validator.VariableValues(0xc0000f1700, 0xc00017c2a0, 0xc000278000, 0xc0001187b0, 0x5)
        /home/jesse/go/pkg/mod/github.com/vektah/[email protected]/validator/vars.go:56 +0x4b2
github.com/99designs/gqlgen/handler.(*graphqlHandler).validateOperation(0xc000114060, 0x9324e0, 0xc000139f80, 0xc000177b20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/jesse/go/pkg/mod/github.com/99designs/[email protected]/handler/graphql.go:622 +0x1de
github.com/99designs/gqlgen/handler.(*graphqlHandler).ServeHTTP(0xc000114060, 0x931a60, 0xc00011e700, 0xc0000f2700)
        /home/jesse/go/pkg/mod/github.com/99designs/[email protected]/handler/graphql.go:511 +0x77b
net/http.HandlerFunc.ServeHTTP(0xc000104020, 0x931a60, 0xc00011e700, 0xc0000f2700)
        /usr/local/go/src/net/http/server.go:2007 +0x44
net/http.(*ServeMux).ServeHTTP(0xbf26c0, 0x931a60, 0xc00011e700, 0xc0000f2700)
        /usr/local/go/src/net/http/server.go:2387 +0x1bd
net/http.serverHandler.ServeHTTP(0xc00011e0e0, 0x931a60, 0xc00011e700, 0xc0000f2700)
        /usr/local/go/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc0000a3180, 0x9324e0, 0xc0000f1d00)
        /usr/local/go/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
        /usr/local/go/src/net/http/server.go:2927 +0x38e

What did you expect?

The value is correctly decoded as nil.

Minimal graphql.schema and models to reproduce

schema.graphql

type Todo {
  id: ID!
}

type Query {
  todos(status: [Status]): [Todo!]!
}

enum Status {
  NEW
  DELETED
}

resolver.go

package gqlgen

import (
	"context"
) // THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.

type Resolver struct{}

func (r *Resolver) Query() QueryResolver {
	return &queryResolver{r}
}

type queryResolver struct{ *Resolver }

func (r *queryResolver) Todos(ctx context.Context, filter []*Status) ([]*Todo, error) {
	return nil, nil
}

gqlgen.yml

# .gqlgen.yml example
#
# Refer to https://gqlgen.com/config/
# for detailed .gqlgen.yml documentation.

schema:
- schema.graphql
exec:
  filename: generated.go
model:
  filename: models_gen.go
resolver:
  filename: resolver.go
  type: Resolver
autobind: []

Used with test server from gqlgen init.

Example curl:

curl 'http://localhost:8080/query' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: http://localhost:8080' --data-binary '{"query":"query Todos($status: [Status]) {\n  todos(status: $status) {\n    id\n  }\n}","variables":{"status":[null]}}' --compressed

versions

  • v0.10.1
  • go version go1.13.4 linux/amd64
  • go modules
@jszwedko
Copy link
Author

jszwedko commented Nov 6, 2019

I validated that this seems to happen with scalars as well (e.g. [String]).

@jszwedko
Copy link
Author

jszwedko commented Nov 6, 2019

Aaaand, I see this was already fixed over here: vektah/gqlparser#104 .

@vektah if you get a chance, I think a release of gqlparser would be helpful :)

I'll pin to the head of gqlparser for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant