From 67795c95b21a60fda303b35e509a447653bc8351 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Mon, 18 Feb 2019 16:34:56 +1100 Subject: [PATCH] Recover from panics in unlikly places --- codegen/args.go | 2 +- codegen/config/binder.go | 8 +- codegen/field.go | 12 +- codegen/object.gotpl | 5 + codegen/testserver/generated.go | 519 +++++++++++++++++++++ codegen/testserver/gqlgen.yml | 4 + codegen/testserver/models.go | 20 +- codegen/testserver/panics.graphql | 12 + codegen/testserver/panics_test.go | 56 +++ codegen/testserver/resolver.go | 15 + codegen/testserver/stub.go | 20 + codegen/type.gotpl | 6 + example/chat/generated.go | 59 +++ example/config/generated.go | 64 +++ example/dataloader/generated.go | 102 ++++ example/scalars/generated.go | 74 +++ example/selection/generated.go | 59 +++ example/starwars/generated.go | 159 +++++++ example/todo/generated.go | 69 +++ example/type-system-extension/generated.go | 64 +++ integration/generated.go | 108 ++++- 21 files changed, 1425 insertions(+), 12 deletions(-) create mode 100644 codegen/testserver/panics.graphql create mode 100644 codegen/testserver/panics_test.go diff --git a/codegen/args.go b/codegen/args.go index b5690e7d78..d1498bddb1 100644 --- a/codegen/args.go +++ b/codegen/args.go @@ -78,7 +78,7 @@ nextArg: } // no matching arg found, abort - return fmt.Errorf("%s is not in schema", param.Name()) + return fmt.Errorf("arg %s not in schema", param.Name()) } field.Args = newArgs diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 873ff371c9..15e456c52e 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -84,7 +84,7 @@ var InterfaceType = types.NewInterfaceType(nil, nil) func (b *Binder) DefaultUserObject(name string) (types.Type, error) { models := b.cfg.Models[name].Model if len(models) == 0 { - return nil, fmt.Errorf(name + " not found") + return nil, fmt.Errorf(name + " not found in typemap") } if models[0] == "map[string]interface{}" { @@ -346,6 +346,10 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret } }() + if len(b.cfg.Models[schemaType.Name()].Model) == 0 { + return nil, fmt.Errorf("%s was not found", schemaType.Name()) + } + for _, model := range b.cfg.Models[schemaType.Name()].Model { if model == "map[string]interface{}" { if !isMap(bindTarget) { @@ -404,7 +408,7 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret return ref, nil } - return nil, fmt.Errorf("not found") + return nil, fmt.Errorf("%s has type compatible with %s", schemaType.Name(), bindTarget.String()) } func (b *Binder) CopyModifiersFromAst(t *ast.Type, usePtr bool, base types.Type) types.Type { diff --git a/codegen/field.go b/codegen/field.go index bab170c9e9..e54e9fdad1 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -62,9 +62,14 @@ func (b *builder) buildField(obj *Object, field *ast.FieldDefinition) (*Field, e } if err = b.bindField(obj, &f); err != nil { + f.IsResolver = true log.Println(err.Error()) } + if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() { + f.TypeReference = b.Binder.PointerTo(f.TypeReference) + } + return &f, nil } @@ -77,10 +82,6 @@ func (b *builder) bindField(obj *Object, f *Field) error { } f.TypeReference = tr } - - if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() { - f.TypeReference = b.Binder.PointerTo(f.TypeReference) - } }() switch { @@ -115,8 +116,6 @@ func (b *builder) bindField(obj *Object, f *Field) error { switch target := target.(type) { case nil: - f.IsResolver = true - objPos := b.Binder.TypePosition(obj.Type) return fmt.Errorf( "%s:%d adding resolver method for %s.%s, nothing matched", @@ -125,6 +124,7 @@ func (b *builder) bindField(obj *Object, f *Field) error { obj.Name, f.Name, ) + case *types.Func: sig := target.Type().(*types.Signature) if sig.Results().Len() == 1 { diff --git a/codegen/object.gotpl b/codegen/object.gotpl index 8966ff77a0..13224ed023 100644 --- a/codegen/object.gotpl +++ b/codegen/object.gotpl @@ -42,6 +42,11 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec {{- if $field.IsConcurrent }} field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) {{- if $field.TypeReference.GQL.NonNull }} if res == graphql.Null { diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 62ccbb2d22..5be0952369 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -40,6 +40,7 @@ type Config struct { type ResolverRoot interface { ForcedResolver() ForcedResolverResolver ModelMethods() ModelMethodsResolver + Panics() PanicsResolver Query() QueryResolver Subscription() SubscriptionResolver User() UserResolver @@ -95,6 +96,12 @@ type ComplexityRoot struct { Inner func(childComplexity int) int } + Panics struct { + FieldScalarMarshal func(childComplexity int) int + FieldFuncMarshal func(childComplexity int, u []MarshalPanic) int + ArgUnmarshal func(childComplexity int, u []MarshalPanic) int + } + Query struct { InvalidIdentifier func(childComplexity int) int Collision func(childComplexity int) int @@ -114,6 +121,7 @@ type ComplexityRoot struct { DirectiveInput func(childComplexity int, arg InputDirectives) int InputSlice func(childComplexity int, arg []string) int ShapeUnion func(childComplexity int) int + Panics func(childComplexity int) int ValidType func(childComplexity int) int } @@ -149,6 +157,11 @@ type ForcedResolverResolver interface { type ModelMethodsResolver interface { ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) } +type PanicsResolver interface { + FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) + + ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) +} type QueryResolver interface { InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) Collision(ctx context.Context) (*introspection1.It, error) @@ -168,6 +181,7 @@ type QueryResolver interface { DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) InputSlice(ctx context.Context, arg []string) (bool, error) ShapeUnion(ctx context.Context) (ShapeUnion, error) + Panics(ctx context.Context) (*Panics, error) ValidType(ctx context.Context) (*ValidType, error) } type SubscriptionResolver interface { @@ -305,6 +319,37 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.OuterObject.Inner(childComplexity), true + case "Panics.FieldScalarMarshal": + if e.complexity.Panics.FieldScalarMarshal == nil { + break + } + + return e.complexity.Panics.FieldScalarMarshal(childComplexity), true + + case "Panics.FieldFuncMarshal": + if e.complexity.Panics.FieldFuncMarshal == nil { + break + } + + args, err := ec.field_Panics_fieldFuncMarshal_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Panics.FieldFuncMarshal(childComplexity, args["u"].([]MarshalPanic)), true + + case "Panics.ArgUnmarshal": + if e.complexity.Panics.ArgUnmarshal == nil { + break + } + + args, err := ec.field_Panics_argUnmarshal_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Panics.ArgUnmarshal(childComplexity, args["u"].([]MarshalPanic)), true + case "Query.InvalidIdentifier": if e.complexity.Query.InvalidIdentifier == nil { break @@ -481,6 +526,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.ShapeUnion(childComplexity), true + case "Query.Panics": + if e.complexity.Query.Panics == nil { + break + } + + return e.complexity.Query.Panics(childComplexity), true + case "Query.ValidType": if e.complexity.Query.ValidType == nil { break @@ -713,6 +765,19 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er } var parsedSchema = gqlparser.MustLoadSchema( + &ast.Source{Name: "panics.graphql", Input: `extend type Query { + panics: Panics +} + +type Panics { + fieldScalarMarshal: [MarshalPanic!]! + fieldFuncMarshal(u: [MarshalPanic!]!): [MarshalPanic!]! + argUnmarshal(u: [MarshalPanic!]!): Boolean! + +} + +scalar MarshalPanic +`}, &ast.Source{Name: "schema.graphql", Input: `type Query { invalidIdentifier: InvalidIdentifier collision: It @@ -957,6 +1022,34 @@ func (ec *executionContext) dir_range_args(ctx context.Context, rawArgs map[stri return args, nil } +func (ec *executionContext) field_Panics_argUnmarshal_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []MarshalPanic + if tmp, ok := rawArgs["u"]; ok { + arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, tmp) + if err != nil { + return nil, err + } + } + args["u"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Panics_fieldFuncMarshal_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []MarshalPanic + if tmp, ok := rawArgs["u"]; ok { + arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, tmp) + if err != nil { + return nil, err + } + } + args["u"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1813,6 +1906,98 @@ func (ec *executionContext) _OuterObject_inner(ctx context.Context, field graphq return ec.marshalNInnerObject2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerObject(ctx, field.Selections, res) } +func (ec *executionContext) _Panics_fieldScalarMarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "Panics", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Panics().FieldScalarMarshal(rctx, obj) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]MarshalPanic) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, field.Selections, res) +} + +func (ec *executionContext) _Panics_fieldFuncMarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "Panics", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Panics_fieldFuncMarshal_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + rctx.Args = args + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.FieldFuncMarshal(ctx, args["u"].([]MarshalPanic)), nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]MarshalPanic) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, field.Selections, res) +} + +func (ec *executionContext) _Panics_argUnmarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "Panics", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Panics_argUnmarshal_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + rctx.Args = args + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Panics().ArgUnmarshal(rctx, obj, args["u"].([]MarshalPanic)) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_invalidIdentifier(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { ec.Tracer.EndFieldExecution(ctx) }() @@ -2309,6 +2494,29 @@ func (ec *executionContext) _Query_shapeUnion(ctx context.Context, field graphql return ec.marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShapeUnion(ctx, field.Selections, res) } +func (ec *executionContext) _Query_panics(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "Query", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Panics(rctx) + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Panics) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPanics(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_validType(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { ec.Tracer.EndFieldExecution(ctx) }() @@ -3980,6 +4188,11 @@ func (ec *executionContext) _ForcedResolver(ctx context.Context, sel ast.Selecti case "field": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._ForcedResolver_field(ctx, field, obj) return res }) @@ -4089,6 +4302,11 @@ func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.Selection case "resolverField": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._ModelMethods_resolverField(ctx, field, obj) if res == graphql.Null { invalid = true @@ -4103,6 +4321,11 @@ func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.Selection case "withContext": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._ModelMethods_withContext(ctx, field, obj) if res == graphql.Null { invalid = true @@ -4147,6 +4370,70 @@ func (ec *executionContext) _OuterObject(ctx context.Context, sel ast.SelectionS return out } +var panicsImplementors = []string{"Panics"} + +func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, obj *Panics) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, panicsImplementors) + + out := graphql.NewFieldSet(fields) + invalid := false + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Panics") + case "fieldScalarMarshal": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Panics_fieldScalarMarshal(ctx, field, obj) + if res == graphql.Null { + invalid = true + } + return res + }) + case "fieldFuncMarshal": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Panics_fieldFuncMarshal(ctx, field, obj) + if res == graphql.Null { + invalid = true + } + return res + }) + case "argUnmarshal": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Panics_argUnmarshal(ctx, field, obj) + if res == graphql.Null { + invalid = true + } + return res + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalid { + return graphql.Null + } + return out +} + var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { @@ -4165,60 +4452,110 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "invalidIdentifier": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_invalidIdentifier(ctx, field) return res }) case "collision": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_collision(ctx, field) return res }) case "mapInput": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_mapInput(ctx, field) return res }) case "recursive": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_recursive(ctx, field) return res }) case "nestedInputs": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_nestedInputs(ctx, field) return res }) case "nestedOutputs": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_nestedOutputs(ctx, field) return res }) case "shapes": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_shapes(ctx, field) return res }) case "errorBubble": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_errorBubble(ctx, field) return res }) case "modelMethods": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_modelMethods(ctx, field) return res }) case "valid": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_valid(ctx, field) if res == graphql.Null { invalid = true @@ -4228,6 +4565,11 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "user": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_user(ctx, field) if res == graphql.Null { invalid = true @@ -4237,36 +4579,66 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "nullableArg": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_nullableArg(ctx, field) return res }) case "directiveArg": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_directiveArg(ctx, field) return res }) case "directiveNullableArg": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_directiveNullableArg(ctx, field) return res }) case "directiveInputNullable": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_directiveInputNullable(ctx, field) return res }) case "directiveInput": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_directiveInput(ctx, field) return res }) case "inputSlice": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_inputSlice(ctx, field) if res == graphql.Null { invalid = true @@ -4276,15 +4648,36 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "shapeUnion": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_shapeUnion(ctx, field) if res == graphql.Null { invalid = true } return res }) + case "panics": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_panics(ctx, field) + return res + }) case "validType": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_validType(ctx, field) return res }) @@ -4372,6 +4765,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "friends": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._User_friends(ctx, field, obj) if res == graphql.Null { invalid = true @@ -4723,6 +5121,44 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return graphql.MarshalInt(v) } +func (ec *executionContext) unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx context.Context, v interface{}) (MarshalPanic, error) { + var res MarshalPanic + return res, res.UnmarshalGQL(v) +} + +func (ec *executionContext) marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx context.Context, sel ast.SelectionSet, v MarshalPanic) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx context.Context, v interface{}) ([]MarshalPanic, error) { + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]MarshalPanic, len(vSlice)) + for i := range vSlice { + res[i], err = ec.unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx context.Context, sel ast.SelectionSet, v []MarshalPanic) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, sel, v[i]) + } + + return ret +} + func (ec *executionContext) unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { return ec.unmarshalInputRecursiveInputSlice(ctx, v) } @@ -4819,6 +5255,12 @@ func (ec *executionContext) marshalNUser2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4864,6 +5306,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4923,6 +5371,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4966,6 +5420,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5001,6 +5461,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5243,6 +5709,12 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99design } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5274,6 +5746,12 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designs } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5297,6 +5775,17 @@ func (ec *executionContext) marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgq return ec._OuterObject(ctx, sel, v) } +func (ec *executionContext) marshalOPanics2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPanics(ctx context.Context, sel ast.SelectionSet, v Panics) graphql.Marshaler { + return ec._Panics(ctx, sel, &v) +} + +func (ec *executionContext) marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPanics(ctx context.Context, sel ast.SelectionSet, v *Panics) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Panics(ctx, sel, v) +} + func (ec *executionContext) unmarshalORecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { return ec.unmarshalInputRecursiveInputSlice(ctx, v) } @@ -5348,6 +5837,12 @@ func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5474,6 +5969,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5505,6 +6006,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5536,6 +6043,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -5582,6 +6095,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/codegen/testserver/gqlgen.yml b/codegen/testserver/gqlgen.yml index c240e129ca..26a1572c51 100644 --- a/codegen/testserver/gqlgen.yml +++ b/codegen/testserver/gqlgen.yml @@ -50,3 +50,7 @@ models: ValidType: fields: different_case: { fieldName: DifferentCaseOld } + Panics: + model: "github.com/99designs/gqlgen/codegen/testserver.Panics" + MarshalPanic: + model: "github.com/99designs/gqlgen/codegen/testserver.MarshalPanic" diff --git a/codegen/testserver/models.go b/codegen/testserver/models.go index 8647046a60..bedcb79011 100644 --- a/codegen/testserver/models.go +++ b/codegen/testserver/models.go @@ -1,8 +1,9 @@ package testserver import ( - context "context" + "context" "fmt" + "io" ) type ForcedResolver struct { @@ -44,3 +45,20 @@ type EmbeddedPointerModel struct { type EmbeddedPointer struct { Title string } + +type MarshalPanic string + +func (m *MarshalPanic) UnmarshalGQL(v interface{}) error { + panic("BOOM") +} + +func (m MarshalPanic) MarshalGQL(w io.Writer) { + panic("BOOM") +} + +type Panics struct { +} + +func (p *Panics) FieldFuncMarshal(ctx context.Context, u []MarshalPanic) []MarshalPanic { + return []MarshalPanic{MarshalPanic("aa"), MarshalPanic("bb")} +} diff --git a/codegen/testserver/panics.graphql b/codegen/testserver/panics.graphql new file mode 100644 index 0000000000..8895fca82c --- /dev/null +++ b/codegen/testserver/panics.graphql @@ -0,0 +1,12 @@ +extend type Query { + panics: Panics +} + +type Panics { + fieldScalarMarshal: [MarshalPanic!]! + fieldFuncMarshal(u: [MarshalPanic!]!): [MarshalPanic!]! + argUnmarshal(u: [MarshalPanic!]!): Boolean! + +} + +scalar MarshalPanic diff --git a/codegen/testserver/panics_test.go b/codegen/testserver/panics_test.go new file mode 100644 index 0000000000..ed7ce713cb --- /dev/null +++ b/codegen/testserver/panics_test.go @@ -0,0 +1,56 @@ +package testserver + +import ( + "context" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/handler" +) + +func TestPanics(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Panics = func(ctx context.Context) (panics *Panics, e error) { + return &Panics{}, nil + } + resolvers.PanicsResolver.ArgUnmarshal = func(ctx context.Context, obj *Panics, u []MarshalPanic) (b bool, e error) { + return true, nil + } + resolvers.PanicsResolver.FieldScalarMarshal = func(ctx context.Context, obj *Panics) (marshalPanic []MarshalPanic, e error) { + return []MarshalPanic{MarshalPanic("aa"), MarshalPanic("bb")}, nil + } + + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(Config{Resolvers: resolvers}))) + c := client.New(srv.URL) + + t.Run("panics in marshallers will not kill server", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { fieldScalarMarshal } }`, &resp) + + require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"internal system error\"}],\"data\":null}") + }) + + t.Run("panics in unmarshalers will not kill server", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { argUnmarshal(u: ["aa", "bb"]) } }`, &resp) + + require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"internal system error\"}],\"data\":null}") + }) + + t.Run("panics in funcs unmarshal return errors", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { fieldFuncMarshal(u: ["aa", "bb"]) } }`, &resp) + + require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"internal system error\"}],\"data\":null}") + }) + + t.Run("panics in funcs marshal return errors", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { fieldFuncMarshal(u: []) } }`, &resp) + + require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"internal system error\"}],\"data\":null}") + }) +} diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index d2b55ca2fc..565a4c6a4e 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -17,6 +17,9 @@ func (r *Resolver) ForcedResolver() ForcedResolverResolver { func (r *Resolver) ModelMethods() ModelMethodsResolver { return &modelMethodsResolver{r} } +func (r *Resolver) Panics() PanicsResolver { + return &panicsResolver{r} +} func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } @@ -39,6 +42,15 @@ func (r *modelMethodsResolver) ResolverField(ctx context.Context, obj *ModelMeth panic("not implemented") } +type panicsResolver struct{ *Resolver } + +func (r *panicsResolver) FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) { + panic("not implemented") +} +func (r *panicsResolver) ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) { + panic("not implemented") +} + type queryResolver struct{ *Resolver } func (r *queryResolver) InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) { @@ -95,6 +107,9 @@ func (r *queryResolver) InputSlice(ctx context.Context, arg []string) (bool, err func (r *queryResolver) ShapeUnion(ctx context.Context) (ShapeUnion, error) { panic("not implemented") } +func (r *queryResolver) Panics(ctx context.Context) (*Panics, error) { + panic("not implemented") +} func (r *queryResolver) ValidType(ctx context.Context) (*ValidType, error) { panic("not implemented") } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index 57e31cc208..1e73236207 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -16,6 +16,10 @@ type Stub struct { ModelMethodsResolver struct { ResolverField func(ctx context.Context, obj *ModelMethods) (bool, error) } + PanicsResolver struct { + FieldScalarMarshal func(ctx context.Context, obj *Panics) ([]MarshalPanic, error) + ArgUnmarshal func(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) + } QueryResolver struct { InvalidIdentifier func(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) Collision func(ctx context.Context) (*introspection1.It, error) @@ -35,6 +39,7 @@ type Stub struct { DirectiveInput func(ctx context.Context, arg InputDirectives) (*string, error) InputSlice func(ctx context.Context, arg []string) (bool, error) ShapeUnion func(ctx context.Context) (ShapeUnion, error) + Panics func(ctx context.Context) (*Panics, error) ValidType func(ctx context.Context) (*ValidType, error) } SubscriptionResolver struct { @@ -52,6 +57,9 @@ func (r *Stub) ForcedResolver() ForcedResolverResolver { func (r *Stub) ModelMethods() ModelMethodsResolver { return &stubModelMethods{r} } +func (r *Stub) Panics() PanicsResolver { + return &stubPanics{r} +} func (r *Stub) Query() QueryResolver { return &stubQuery{r} } @@ -74,6 +82,15 @@ func (r *stubModelMethods) ResolverField(ctx context.Context, obj *ModelMethods) return r.ModelMethodsResolver.ResolverField(ctx, obj) } +type stubPanics struct{ *Stub } + +func (r *stubPanics) FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) { + return r.PanicsResolver.FieldScalarMarshal(ctx, obj) +} +func (r *stubPanics) ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) { + return r.PanicsResolver.ArgUnmarshal(ctx, obj, u) +} + type stubQuery struct{ *Stub } func (r *stubQuery) InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) { @@ -130,6 +147,9 @@ func (r *stubQuery) InputSlice(ctx context.Context, arg []string) (bool, error) func (r *stubQuery) ShapeUnion(ctx context.Context) (ShapeUnion, error) { return r.QueryResolver.ShapeUnion(ctx) } +func (r *stubQuery) Panics(ctx context.Context) (*Panics, error) { + return r.QueryResolver.Panics(ctx) +} func (r *stubQuery) ValidType(ctx context.Context) (*ValidType, error) { return r.QueryResolver.ValidType(ctx) } diff --git a/codegen/type.gotpl b/codegen/type.gotpl index 6fadb4424f..ce766d3c5f 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -80,6 +80,12 @@ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/chat/generated.go b/example/chat/generated.go index 5827c738d4..845ab1658e 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -1650,6 +1650,11 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "room": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_room(ctx, field) return res }) @@ -1968,6 +1973,12 @@ func (ec *executionContext) marshalNMessage2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2035,6 +2046,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2094,6 +2111,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2137,6 +2160,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2172,6 +2201,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2278,6 +2313,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2309,6 +2350,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2340,6 +2387,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2386,6 +2439,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/config/generated.go b/example/config/generated.go index b78e835eca..97a7dd2c8a 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -1501,6 +1501,11 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "todos": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_todos(ctx, field) if res == graphql.Null { invalid = true @@ -1536,6 +1541,11 @@ func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj case "id": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Todo_id(ctx, field, obj) if res == graphql.Null { invalid = true @@ -1905,6 +1915,12 @@ func (ec *executionContext) marshalNTodo2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -1954,6 +1970,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2013,6 +2035,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2056,6 +2084,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2091,6 +2125,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2186,6 +2226,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2217,6 +2263,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2248,6 +2300,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2294,6 +2352,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index f09ad400dc..f2d965d06e 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -1701,12 +1701,22 @@ func (ec *executionContext) _Customer(ctx context.Context, sel ast.SelectionSet, case "address": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Customer_address(ctx, field, obj) return res }) case "orders": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Customer_orders(ctx, field, obj) return res }) @@ -1777,6 +1787,11 @@ func (ec *executionContext) _Order(ctx context.Context, sel ast.SelectionSet, ob case "items": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Order_items(ctx, field, obj) return res }) @@ -1809,18 +1824,33 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "customers": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_customers(ctx, field) return res }) case "torture1d": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_torture1d(ctx, field) return res }) case "torture2d": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_torture2d(ctx, field) return res }) @@ -2161,6 +2191,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2220,6 +2256,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2263,6 +2305,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2298,6 +2346,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2381,6 +2435,12 @@ func (ec *executionContext) marshalOCustomer2ᚕgithubᚗcomᚋ99designsᚋgqlge } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2412,6 +2472,12 @@ func (ec *executionContext) marshalOCustomer2ᚕᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2501,6 +2567,12 @@ func (ec *executionContext) marshalOItem2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2532,6 +2604,12 @@ func (ec *executionContext) marshalOOrder2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2586,6 +2664,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2617,6 +2701,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2648,6 +2738,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2694,6 +2790,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/scalars/generated.go b/example/scalars/generated.go index 34e955ca8e..08bcab5f8a 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -1613,12 +1613,22 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "user": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_user(ctx, field) return res }) case "search": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_search(ctx, field) if res == graphql.Null { invalid = true @@ -1671,6 +1681,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "primitiveResolver": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._User_primitiveResolver(ctx, field, obj) if res == graphql.Null { invalid = true @@ -1680,6 +1695,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "customResolver": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._User_customResolver(ctx, field, obj) if res == graphql.Null { invalid = true @@ -2025,6 +2045,12 @@ func (ec *executionContext) marshalNUser2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2060,6 +2086,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2119,6 +2151,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2162,6 +2200,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2197,6 +2241,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2387,6 +2437,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2418,6 +2474,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2449,6 +2511,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2495,6 +2563,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/selection/generated.go b/example/selection/generated.go index 3692f5a0e1..a15fc7fcaa 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -1470,6 +1470,11 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "events": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_events(ctx, field) return res }) @@ -1786,6 +1791,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -1845,6 +1856,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -1888,6 +1905,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -1923,6 +1946,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -1995,6 +2024,12 @@ func (ec *executionContext) marshalOEvent2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2078,6 +2113,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2109,6 +2150,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2140,6 +2187,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2186,6 +2239,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/starwars/generated.go b/example/starwars/generated.go index 5a2a083ce4..99116eac69 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -2921,12 +2921,22 @@ func (ec *executionContext) _Droid(ctx context.Context, sel ast.SelectionSet, ob case "friends": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Droid_friends(ctx, field, obj) return res }) case "friendsConnection": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Droid_friendsConnection(ctx, field, obj) if res == graphql.Null { invalid = true @@ -2970,12 +2980,22 @@ func (ec *executionContext) _FriendsConnection(ctx context.Context, sel ast.Sele case "edges": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._FriendsConnection_edges(ctx, field, obj) return res }) case "friends": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._FriendsConnection_friends(ctx, field, obj) return res }) @@ -3055,12 +3075,22 @@ func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, ob case "friends": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Human_friends(ctx, field, obj) return res }) case "friendsConnection": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Human_friendsConnection(ctx, field, obj) if res == graphql.Null { invalid = true @@ -3075,6 +3105,11 @@ func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, ob case "starships": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Human_starships(ctx, field, obj) return res }) @@ -3172,12 +3207,22 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "hero": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_hero(ctx, field) return res }) case "reviews": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_reviews(ctx, field) if res == graphql.Null { invalid = true @@ -3187,6 +3232,11 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "search": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_search(ctx, field) if res == graphql.Null { invalid = true @@ -3196,24 +3246,44 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "character": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_character(ctx, field) return res }) case "droid": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_droid(ctx, field) return res }) case "human": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_human(ctx, field) return res }) case "starship": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_starship(ctx, field) return res }) @@ -3287,6 +3357,11 @@ func (ec *executionContext) _Starship(ctx context.Context, sel ast.SelectionSet, case "length": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Starship_length(ctx, field, obj) if res == graphql.Null { invalid = true @@ -3610,6 +3685,12 @@ func (ec *executionContext) marshalNEpisode2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -3749,6 +3830,12 @@ func (ec *executionContext) marshalNReview2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -3788,6 +3875,12 @@ func (ec *executionContext) marshalNSearchResult2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -3835,6 +3928,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -3894,6 +3993,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -3937,6 +4042,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -3972,6 +4083,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4048,6 +4165,12 @@ func (ec *executionContext) marshalOCharacter2ᚕgithubᚗcomᚋ99designsᚋgqlg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4122,6 +4245,12 @@ func (ec *executionContext) marshalOFriendsEdge2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4249,6 +4378,12 @@ func (ec *executionContext) marshalOStarship2ᚕgithubᚗcomᚋ99designsᚋgqlge } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4336,6 +4471,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4367,6 +4508,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4398,6 +4545,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -4444,6 +4597,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/todo/generated.go b/example/todo/generated.go index cd535e1e49..1db0bd6ebf 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -1562,18 +1562,33 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) case "todo": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._MyQuery_todo(ctx, field) return res }) case "lastTodo": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._MyQuery_lastTodo(ctx, field) return res }) case "todos": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._MyQuery_todos(ctx, field) if res == graphql.Null { invalid = true @@ -1937,6 +1952,12 @@ func (ec *executionContext) marshalNTodo2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -1986,6 +2007,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2045,6 +2072,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2088,6 +2121,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2123,6 +2162,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2229,6 +2274,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2260,6 +2311,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2291,6 +2348,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2337,6 +2400,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index 5633266ab3..e21dae94c4 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -1586,6 +1586,11 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) case "todos": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._MyQuery_todos(ctx, field) if res == graphql.Null { invalid = true @@ -1595,6 +1600,11 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) case "todo": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._MyQuery_todo(ctx, field) return res }) @@ -1952,6 +1962,12 @@ func (ec *executionContext) marshalNTodo2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋ } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2001,6 +2017,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2060,6 +2082,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2103,6 +2131,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2138,6 +2172,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2244,6 +2284,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2275,6 +2321,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2306,6 +2358,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2352,6 +2410,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } diff --git a/integration/generated.go b/integration/generated.go index 40cab9ab1f..a9044e3f50 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -72,6 +72,7 @@ type ComplexityRoot struct { type ElementResolver interface { Child(ctx context.Context, obj *models.Element) (*models.Element, error) Error(ctx context.Context, obj *models.Element) (bool, error) + Mismatched(ctx context.Context, obj *models.Element) ([]bool, error) } type QueryResolver interface { Path(ctx context.Context) ([]*models.Element, error) @@ -477,7 +478,7 @@ func (ec *executionContext) _Element_mismatched(ctx context.Context, field graph ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Mismatched, nil + return ec.resolvers.Element().Mismatched(rctx, obj) }) if resTmp == nil { return graphql.Null @@ -1612,6 +1613,11 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, case "child": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Element_child(ctx, field, obj) if res == graphql.Null { invalid = true @@ -1621,6 +1627,11 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, case "error": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Element_error(ctx, field, obj) if res == graphql.Null { invalid = true @@ -1628,7 +1639,16 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, return res }) case "mismatched": - out.Values[i] = ec._Element_mismatched(ctx, field, obj) + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Element_mismatched(ctx, field, obj) + return res + }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1658,12 +1678,22 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "path": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_path(ctx, field) return res }) case "date": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_date(ctx, field) if res == graphql.Null { invalid = true @@ -1673,12 +1703,22 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "viewer": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_viewer(ctx, field) return res }) case "jsonEncoding": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_jsonEncoding(ctx, field) if res == graphql.Null { invalid = true @@ -1688,6 +1728,11 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr case "error": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._Query_error(ctx, field) if res == graphql.Null { invalid = true @@ -1728,6 +1773,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "likes": field := field out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() res = ec._User_likes(ctx, field, obj) if res == graphql.Null { invalid = true @@ -2096,6 +2146,12 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2155,6 +2211,12 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstring(ctx context.Co } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2198,6 +2260,12 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2233,6 +2301,12 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2362,6 +2436,12 @@ func (ec *executionContext) marshalOElement2ᚕᚖgithubᚗcomᚋ99designsᚋgql } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2492,6 +2572,12 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2523,6 +2609,12 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2554,6 +2646,12 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -2600,6 +2698,12 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } ctx := graphql.WithResolverContext(ctx, rctx) f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() }