Skip to content

Commit

Permalink
more actionable federation errors for nil key field queries (#3437)
Browse files Browse the repository at this point in the history
* Better federation errors

Signed-off-by: Steve Coffman <steve@khanacademy.org>

* Regenerate

Signed-off-by: Steve Coffman <steve@khanacademy.org>

* Run tests to reset federation testdata

Signed-off-by: Steve Coffman <steve@khanacademy.org>

---------

Signed-off-by: Steve Coffman <steve@khanacademy.org>
  • Loading branch information
StevenACoffman authored Dec 16, 2024
1 parent 2a8d141 commit 0d2b9d2
Show file tree
Hide file tree
Showing 11 changed files with 802 additions and 77 deletions.
20 changes: 18 additions & 2 deletions _examples/federation/accounts/graph/federation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 29 additions & 2 deletions _examples/federation/products/graph/federation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 25 additions & 2 deletions _examples/federation/reviews/graph/federation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion plugin/federation/federation.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ func (ec *executionContext) resolveManyEntities(
{{- if .Resolvers }}

func entityResolverNameFor{{$entity.Name}}(ctx context.Context, rep EntityRepresentation) (string, error) {
// we collect errors because a later entity resolver may work fine
// when an entity has multiple keys
entityResolverErrs := []error{}
{{- range .Resolvers }}
for {
var (
Expand All @@ -310,10 +313,15 @@ func (ec *executionContext) resolveManyEntities(
{{- range $i, $field := .Field }}
val, ok = m["{{.}}"]
if !ok {
entityResolverErrs = append(entityResolverErrs,
fmt.Errorf("%w due to missing Key Field \"{{.}}\" for {{$entity.Name}}", ErrTypeNotFound))
break
}
{{- if (ne $i $keyField.Field.LastIndex ) }}
if m, ok = val.(map[string]interface{}); !ok {
// nested field value is not a map[string]interface so don't use it
entityResolverErrs = append(entityResolverErrs,
fmt.Errorf("%w due to nested Key Field \"{{.}}\" value not matching map[string]any for {{$entity.Name}}", ErrTypeNotFound))
break
}
{{- else}}
Expand All @@ -324,12 +332,15 @@ func (ec *executionContext) resolveManyEntities(
{{- end}}
{{- end }}
if allNull {
entityResolverErrs = append(entityResolverErrs,
fmt.Errorf("%w due to all null value KeyFields for {{$entity.Name}}", ErrTypeNotFound))
break
}
return "{{.ResolverName}}", nil
}
{{- end }}
return "", fmt.Errorf("%w for {{$entity.Name}}", ErrTypeNotFound)
return "", fmt.Errorf("%w for {{$entity.Name}} due to %v", ErrTypeNotFound,
errors.Join(entityResolverErrs...).Error())
}
{{- end }}
{{- end }}
Expand Down
10 changes: 5 additions & 5 deletions plugin/federation/federation_entityresolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,12 @@ func TestEntityResolver(t *testing.T) {
Bar int `json:"bar"`
} `json:"_entities"`
}

eq := entityQuery([]string{
"WorldWithMultipleKeys {foo hello {name}}",
"WorldWithMultipleKeys {bar}",
})
err := c.Post(
entityQuery([]string{
"WorldWithMultipleKeys {foo hello {name}}",
"WorldWithMultipleKeys {bar}",
}),
eq,
&resp,
client.Var("representations", representations),
)
Expand Down
Loading

0 comments on commit 0d2b9d2

Please sign in to comment.