Element is null, which is not allowed error when errors are added to context only
- 主要语言
- Go
- 星标
- 10.8k
- 派生
- 1.3k
- 平均合并
- 2 天 36 分钟
- 30 天内合并 PR
- 26
描述
I'm getting error `the requested element is null which the schema does not allow` when adding errors to the GraphQL context and `return nil, nil` from resolver.
I have this query defined and resolver below. If I'm returning `nil, err` it is fine. I see proper GraphQL error response. Meaning `{"data": null, "errors": ...}`.
But in second case, I can get mutli error from `payload.BuildURL`. Based on error type inside I can differentiate which input was wrong.
However, that fails with `the requested element is null which the schema does not allow`. And to me that is strange.
I understand, that in schema I have non-nullable response. And if I would see that error in both cases (returning error directly and adding to context) it would be fine. But this is strange.
```graphql
query {
externalDataResolverReplacePlaceholders(
config: ExternalDataResolverConfigInput!
values: Map
): ExternalDataResolverReplacedPlaceholders!
}
```
Resolver:
```go
func ErrorOnPath(ctx context.Context, err error, path ...string) error {
gqlErr = gqlerror.WrapPath(graphql.GetPath(ctx), err)
for _, v := range path {
gqlErr.Path = append(gqlErr.Path, ast.PathName(v))
}
return gqlErr
}
func (*queryResolver) ExternalDataResolverReplacePlaceholders(
ctx context.Context,
cfg model.ExternalDataResolverConfigInput,
values map[string]any,
) (*model.ExternalDataResolverReplacedPlaceholders, error) {
if uri, err := url.Parse(cfg.URL); err != nil || !uri.IsAbs() {
// Here I return nil as response together with error and it is fine
return nil, ErrorOnPath(ctx, errors.New("URL must be valid and absolute"), "config", "URL")
}
resp := &model.ExternalDataResolverReplacedPlaceholders{}
var err error
resp.URL, err = payload.BuildURL(cfg.URL, values)
if err != nil {
if me, ok := err.(*payload.MultiError); ok {
for _, e := range me.Errors {
switch e := e.(type) {
case *payload.MissingVariableError:
graphql.AddError(ctx, ErrorOnPath(ctx, e, "values"))
case *payload.InvalidDefaultValueError:
graphql.AddError(ctx, ErrorOnPath(ctx, e, "config", "URL"))
}
}
// Here if I return nil, and all errors are added to context, this is an issue
return nil, nil
}
return nil, ErrorOnPath(ctx, err, "config", "URL")
}
return resp, nil
}
```
---
I was debugging that deeper into generated code, and I spot 1 place which causes the trouble I believe. But not sure if fixing that wouldn't break the rest of the code.
When I was debugging, I got here in generated code:
```go
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
return graphql.Null
}
```
`v` in my case is `nil` so it is checking if field has error with this code. But when it goes to `equalPath`, input parameters are follow:
- `path` contains `["externalDataResolverReplacePlaceholders"]`
- `err.Path` contains `["externalDataResolverReplacePlaceholders", "values"]`
so `equalPath` returns false, which means that HasFieldError is false too and then I see the `"the requested element is null..."` error.
```go
func HasFieldError(ctx context.Context, rctx *FieldContext) bool {
...
for _, err := range c.errors {
if equalPath(err.Path, path) {
return true
}
}
...
}
```
贡献指南
评估
这个 Issue 还没有评估数据。