Open mihirpmehta opened 1 year ago
The non compilable code is following
func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity {
list := make([]fedruntime.Entity, len(representations))
repsMap := map[string]struct {
i []int
r []map[string]interface{}
}{}
// We group entities by typename so that we can parallelize their resolution.
// This is particularly helpful when there are entity groups in multi mode.
buildRepresentationGroups := func(reps []map[string]interface{}) {
for i, rep := range reps {
typeName, ok := rep["__typename"].(string)
if !ok {
// If there is no __typename, we just skip the representation;
// we just won't be resolving these unknown types.
ec.Error(ctx, errors.New("__typename must be an existing string"))
continue
}
_r := repsMap[typeName]
_r.i = append(_r.i, i)
_r.r = append(_r.r, rep)
repsMap[typeName] = _r
}
}
isMulti := func(typeName string) bool {
switch typeName {
default:
return false
}
}
resolveEntity := func(ctx context.Context, typeName string, rep map[string]interface{}, idx []int, i int) (err error) {
// we need to do our own panic handling, because we may be called in a
// goroutine, where the usual panic handling can't catch us
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
}
}()
switch typeName {
case "Book":
resolverName, err := entityResolverNameForBook(ctx, rep)
if err != nil {
return fmt.Errorf(`finding resolver for Entity "Book": %w`, err)
}
switch resolverName {
case "findBookByID":
id0, err := ec.unmarshalNID2string(ctx, rep["id"])
if err != nil {
return fmt.Errorf(`unmarshalling param 0 for findBookByID(): %w`, err)
}
entity, err := ec.resolvers.Entity().FindBookByID(ctx, id0)
if err != nil {
return fmt.Errorf(`resolving Entity "Book": %w`, err)
}
// THIS LINE IS INCORRECT
entity.Publishers.Name, err = ec.unmarshalOString2ᚖstring(ctx, rep["publishers"].(map[string]interface{})["name"])
if err != nil {
return err
}
list[idx[i]] = entity
return nil
}
case "Review":
resolverName, err := entityResolverNameForReview(ctx, rep)
if err != nil {
return fmt.Errorf(`finding resolver for Entity "Review": %w`, err)
}
switch resolverName {
case "findReviewByID":
id0, err := ec.unmarshalNID2string(ctx, rep["id"])
if err != nil {
return fmt.Errorf(`unmarshalling param 0 for findReviewByID(): %w`, err)
}
entity, err := ec.resolvers.Entity().FindReviewByID(ctx, id0)
if err != nil {
return fmt.Errorf(`resolving Entity "Review": %w`, err)
}
list[idx[i]] = entity
return nil
}
}
return fmt.Errorf("%w: %s", ErrUnknownType, typeName)
}
resolveManyEntities := func(ctx context.Context, typeName string, reps []map[string]interface{}, idx []int) (err error) {
// we need to do our own panic handling, because we may be called in a
// goroutine, where the usual panic handling can't catch us
defer func() {
if r := recover(); r != nil {
err = ec.Recover(ctx, r)
}
}()
switch typeName {
default:
return errors.New("unknown type: " + typeName)
}
}
resolveEntityGroup := func(typeName string, reps []map[string]interface{}, idx []int) {
if isMulti(typeName) {
err := resolveManyEntities(ctx, typeName, reps, idx)
if err != nil {
ec.Error(ctx, err)
}
} else {
// if there are multiple entities to resolve, parallelize (similar to
// graphql.FieldSet.Dispatch)
var e sync.WaitGroup
e.Add(len(reps))
for i, rep := range reps {
i, rep := i, rep
go func(i int, rep map[string]interface{}) {
err := resolveEntity(ctx, typeName, rep, idx, i)
if err != nil {
ec.Error(ctx, err)
}
e.Done()
}(i, rep)
}
e.Wait()
}
}
buildRepresentationGroups(representations)
switch len(repsMap) {
case 0:
return list
case 1:
for typeName, reps := range repsMap {
resolveEntityGroup(typeName, reps.r, reps.i)
}
return list
default:
var g sync.WaitGroup
g.Add(len(repsMap))
for typeName, reps := range repsMap {
go func(typeName string, reps []map[string]interface{}, idx []int) {
resolveEntityGroup(typeName, reps, idx)
g.Done()
}(typeName, reps.r, reps.i)
}
g.Wait()
return list
}
}
What happened?
gqlgen generates non compilable code when schema has uses @requires directive with array nested attribute dependency for federation. in federation.go file i.e. see the sample schema that is mentioned below
What did you expect?
It should generate compilable code
Minimal graphql.schema and models to reproduce
versions
go run github.com/99designs/gqlgen version
? v0.17.31go version
? go1.20.3 darwin/amd64if you try to run ----
it will generate error validation failed: packages.Load: /graph/generated/federation.go:100 : 23: entity.Publishers.Name undefined (type []*model.Publishers has no field or method Name)
on this line in federation.go file
entity.Publishers.Name, err = ec.unmarshalOString2ᚖstring(ctx, rep["publishers"].(map[string]interface{})["name"])
This is because Publishers.Name is incorrect ... Publishers is array