When performing introspection, s.Meta is nil here, resulting in a panic when trying to access s.Meta.Schema: https://github.com/graph-gophers/graphql-go/pull/322/files#diff-b6bf573d68ccde9452577f66f6c4e89aR96
Unfortunately, I'm lacking in contextual knowledge about this codebase to efficiently debug _why_ s.Meta is nil, but moving backwards in the commit log to prior to this change (commit fde50bb) works fine.
@bmhatfield are you able to share more details about the panic you're seeing? On 2 different schemas we use, I'm not seeing any errors in the Introspection queries for them, so I'm unsure where this is occurring
Happy to - I was hoping this was just an oversight and not specific to my environment.
The panic is evident for me when on commit b068bc1, but not on fde50bb.
I have a somewhat complex schema and approach to calling into introspection;
In the below panic, Export is effectively doing this:
graphql.MustParseSchema(fullSchema, graphQLAPI.Resolver).ToJSON().
fullSchema is a multi-hundred line schema which parses and is able to serve graphql correctly even when on b068bc1; it is only introspection that fails.
Via a process of printf debugging, I was able to determine that s.Meta was nil in selected.applySelectionSet, while s is otherwise intact:
&resolvable.Schema{Meta:(*resolvable.Meta)(nil), Schema:schema.Schema{EntryPoints:map[string]schema.NamedType{"mutation":(*schema.Object)(0xc0003dbb90), "query":(*schema.Object)(0xc0003da230)}, Types:map[string]schema.NamedType{ TYPE MAP TRIMMED BY HAND }, Directives:map[string]*schema.DirectiveDecl{"deprecated":(*schema.DirectiveDecl)(0xc00027e870), "include":(*schema.DirectiveDecl)(0xc00027e7d0), "skip":(*schema.DirectiveDecl)(0xc00027e820)}, UseFieldResolvers:false, entryPointNames:map[string]string{"mutation":"Mutation", "query":"Query"}, objects:[]*schema.Object{ OBEJECTS TRIMMED BY HAND }}, Query:(*resolvable.Object)(0xc0000ac340), Mutation:resolvable.Resolvable(nil), Subscription:resolvable.Resolvable(nil), Resolver:reflect.Value{typ:(*reflect.rtype)(nil), ptr:(unsafe.Pointer)(nil), flag:0x0}}
The full panic is below:
2019/05/07 21:49:48 graphql: panic occurred: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
github.com/graph-gophers/graphql-go/log.(*DefaultLogger).LogPanic(0x23544d0, 0x1c08440, 0xc000199d70, 0x18c6ea0, 0x2318650)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/log/log.go:21 +0x6d
github.com/graph-gophers/graphql-go/internal/exec.(*Request).handlePanic(0xc00015c000, 0x1c08440, 0xc000199d70)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/internal/exec/exec.go:30 +0x8d
panic(0x18c6ea0, 0x2318650)
/usr/local/Cellar/go/1.12.5/libexec/src/runtime/panic.go:522 +0x1b5
github.com/graph-gophers/graphql-go/internal/exec/selected.applySelectionSet(0xc00015c000, 0xc00001a480, 0xc00000fb80, 0xc000184ae0, 0x1, 0x1, 0xc0005ada90, 0x18, 0xc0005ada88)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go:96 +0xb2d
github.com/graph-gophers/graphql-go/internal/exec/selected.ApplyOperation(0xc00015c000, 0xc00001a480, 0xc0003682d0, 0x1c08440, 0xc000199d70, 0x30)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go:42 +0x9c
github.com/graph-gophers/graphql-go/internal/exec.(*Request).Execute.func1(0xc00015c000, 0x1c08440, 0xc000199d70, 0xc00001a480, 0xc0003682d0, 0xc0005adb58)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/internal/exec/exec.go:47 +0x8f
github.com/graph-gophers/graphql-go/internal/exec.(*Request).Execute(0xc00015c000, 0x1c08440, 0xc000199d70, 0xc00001a480, 0xc0003682d0, 0x0, 0x0, 0xc000199d10, 0xc000199d40, 0x1c08440, ...)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/internal/exec/exec.go:49 +0x94
github.com/graph-gophers/graphql-go.(*Schema).exec(0xc0000cdb60, 0x1c083c0, 0xc0000e4048, 0x1a3af3d, 0x590, 0x0, 0x0, 0xc000199d10, 0xc00001a480, 0x3)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/graphql.go:213 +0x7eb
github.com/graph-gophers/graphql-go.(*Schema).ToJSON(0xc0000cdb60, 0xc0000cdb60, 0x1a324a9, 0xf, 0xc000426f80, 0x18d5a00)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/introspection.go:18 +0x101
github.com/digits/go-services/services/external-apis/dashboard/api.(*GraphQLAPI).Export(0x2321240, 0x7ffeefbff934, 0x5d)
/Users/bhatfield/go/src/github.com/digits/go-services/services/external-apis/dashboard/api/graphql.go:113 +0x4e
github.com/digits/go-services/services/external-apis/dashboard/api.ExportSchema(0x7ffeefbff934, 0x5d, 0xc0000f6b00, 0x4, 0x4)
/Users/bhatfield/go/src/github.com/digits/go-services/services/external-apis/dashboard/api/api.go:61 +0x237
main.main()
/Users/bhatfield/go/src/github.com/digits/go-services/services/external-apis/dashboard/main.go:89 +0x6a1
panic: graphql: graphql: panic occurred: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
github.com/graph-gophers/graphql-go.(*Schema).ToJSON(0xc0000cdb60, 0xc0000cdb60, 0x1a324a9, 0xf, 0xc000426f80, 0x18d5a00)
/Users/bhatfield/go/src/github.com/graph-gophers/graphql-go/introspection.go:23 +0x21a
github.com/digits/go-services/services/external-apis/dashboard/api.(*GraphQLAPI).Export(0x2321240, 0x7ffeefbff934, 0x5d)
/Users/bhatfield/go/src/github.com/digits/go-services/services/external-apis/dashboard/api/graphql.go:113 +0x4e
github.com/digits/go-services/services/external-apis/dashboard/api.ExportSchema(0x7ffeefbff934, 0x5d, 0xc0000f6b00, 0x4, 0x4)
/Users/bhatfield/go/src/github.com/digits/go-services/services/external-apis/dashboard/api/api.go:61 +0x237
main.main()
/Users/bhatfield/go/src/github.com/digits/go-services/services/external-apis/dashboard/main.go:89 +0x6a1
exit status 2
@bmhatfield are you able to isolate the issue and figure out which part of the schema causes this?
This appears to be something specific to the introspection ToJSON case. Introspection queries invoked by GraphiQL work fine, but it seems that there is an issue with the ToJSON case, where the required meta schema mustn't be available.
Working on a fix now
@dackroyd does that imply you're able to reproduce/see at this point? Carving up my schema to try and isolate the issue when there aren't schema changes to bisect on is going to be a really big task :-(
Correct - I've reproduced the issue in the library itself, using the Star Wars schema. The issue is here:
// ToJSON encodes the schema in a JSON format used by tools like Relay.
func (s *Schema) ToJSON() ([]byte, error) {
result := s.exec(context.Background(), introspectionQuery, "", nil, &resolvable.Schema{ // resolvable.Schema has no 'Meta'
Query: &resolvable.Object{},
Schema: *s.schema,
})
if len(result.Errors) != 0 {
panic(result.Errors[0])
}
return json.MarshalIndent(result.Data, "", "\t")
}
When invoked via the Relay handler, the resolvable.Schema is set to s.res, from the actual resolver that has been attached to the schema.
Fix should be trivial - confirming details.
@bmhatfield can you confirm that this doesn't happen anymore?
Most helpful comment
Correct - I've reproduced the issue in the library itself, using the Star Wars schema. The issue is here:
When invoked via the Relay handler, the
resolvable.Schemais set tos.res, from the actual resolver that has been attached to the schema.Fix should be trivial - confirming details.