diff --git a/graphql/handler/server_test.go b/graphql/handler/server_test.go index 606e93f17ea..e00d06a8d69 100644 --- a/graphql/handler/server_test.go +++ b/graphql/handler/server_test.go @@ -2,6 +2,7 @@ package handler_test import ( "context" + "fmt" "net/http" "net/http/httptest" "net/url" @@ -162,6 +163,27 @@ func TestErrorServer(t *testing.T) { }) } +type panicTransport struct{} + +func (t panicTransport) Supports(r *http.Request) bool { + return true +} + +func (h panicTransport) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + panic(fmt.Errorf("panic in transport")) +} + +func TestRecover(t *testing.T) { + srv := testserver.New() + srv.AddTransport(&panicTransport{}) + + t.Run("recover from panic", func(t *testing.T) { + resp := get(srv, "/foo?query={name}") + + assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) + }) +} + func get(handler http.Handler, target string) *httptest.ResponseRecorder { r := httptest.NewRequest("GET", target, nil) w := httptest.NewRecorder() diff --git a/graphql/recovery.go b/graphql/recovery.go index 3aa032dc5aa..9bc0e47e1df 100644 --- a/graphql/recovery.go +++ b/graphql/recovery.go @@ -2,10 +2,11 @@ package graphql import ( "context" - "errors" "fmt" "os" "runtime/debug" + + "github.com/vektah/gqlparser/v2/gqlerror" ) type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error) @@ -15,5 +16,5 @@ func DefaultRecover(ctx context.Context, err interface{}) error { fmt.Fprintln(os.Stderr) debug.PrintStack() - return errors.New("internal system error") + return gqlerror.Errorf("internal system error") }