Skip to content

Commit

Permalink
Ensure panic handlers get applied
Browse files Browse the repository at this point in the history
  • Loading branch information
vektah committed Feb 18, 2020
1 parent 1a68df3 commit 2340f7a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 26 deletions.
26 changes: 21 additions & 5 deletions codegen/testserver/panics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package testserver

import (
"context"
"fmt"
"testing"

"github.com/99designs/gqlgen/graphql"

"github.com/99designs/gqlgen/client"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/stretchr/testify/require"
"github.com/vektah/gqlparser/v2/gqlerror"
)

func TestPanics(t *testing.T) {
Expand All @@ -21,33 +25,45 @@ func TestPanics(t *testing.T) {
return []MarshalPanic{MarshalPanic("aa"), MarshalPanic("bb")}, nil
}

c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})))
srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))
srv.SetRecoverFunc(func(ctx context.Context, err interface{}) (userMessage error) {
return fmt.Errorf("panic: %v", err)
})

srv.SetErrorPresenter(func(ctx context.Context, err error) *gqlerror.Error {
return &gqlerror.Error{
Message: "presented: " + err.Error(),
Path: graphql.GetFieldContext(ctx).Path(),
}
})

c := client.New(srv)

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}")
require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"presented: panic: BOOM\"}],\"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, "[{\"message\":\"internal system error\",\"path\":[\"panics\",\"argUnmarshal\"]}]")
require.EqualError(t, err, "[{\"message\":\"presented: panic: BOOM\",\"path\":[\"panics\",\"argUnmarshal\"]}]")
})

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, "[{\"message\":\"internal system error\",\"path\":[\"panics\",\"fieldFuncMarshal\"]}]")
require.EqualError(t, err, "[{\"message\":\"presented: panic: BOOM\",\"path\":[\"panics\",\"fieldFuncMarshal\"]}]")
})

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}")
require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"presented: panic: BOOM\"}],\"data\":null}")
})
}
2 changes: 1 addition & 1 deletion graphql/handler/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (e executor) DispatchOperation(ctx context.Context, rc *graphql.OperationCo
func (e executor) CreateOperationContext(ctx context.Context, params *graphql.RawParams) (*graphql.OperationContext, gqlerror.List) {
rc := &graphql.OperationContext{
DisableIntrospection: true,
Recover: graphql.DefaultRecover,
Recover: e.server.recoverFunc,
ResolverMiddleware: e.fieldMiddleware,
Stats: graphql.Stats{
Read: params.ReadTime,
Expand Down
20 changes: 0 additions & 20 deletions graphql/recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"fmt"
"os"
"runtime/debug"

"github.com/vektah/gqlparser/v2/gqlerror"
)

type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error)
Expand All @@ -19,21 +17,3 @@ func DefaultRecover(ctx context.Context, err interface{}) error {

return errors.New("internal system error")
}

var _ OperationContextMutator = RecoverFunc(nil)

func (f RecoverFunc) ExtensionName() string {
return "RecoverFunc"
}

func (f RecoverFunc) Validate(schema ExecutableSchema) error {
if f == nil {
return fmt.Errorf("RecoverFunc can not be nil")
}
return nil
}

func (f RecoverFunc) MutateOperationContext(ctx context.Context, rc *OperationContext) *gqlerror.Error {
rc.Recover = f
return nil
}

0 comments on commit 2340f7a

Please sign in to comment.