From 8c25a9a4624971fa24f91d4a5a7ff826bbeb811e Mon Sep 17 00:00:00 2001 From: Lucas Teske Date: Sat, 8 Sep 2018 20:44:31 -0300 Subject: [PATCH 1/3] Added holder for originalError in FormattedError --- gqlerrors/formatted.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/gqlerrors/formatted.go b/gqlerrors/formatted.go index dc60f302..48d7c060 100644 --- a/gqlerrors/formatted.go +++ b/gqlerrors/formatted.go @@ -12,10 +12,15 @@ type ExtendedError interface { } type FormattedError struct { - Message string `json:"message"` - Locations []location.SourceLocation `json:"locations"` - Path []interface{} `json:"path,omitempty"` - Extensions map[string]interface{} `json:"extensions,omitempty"` + Message string `json:"message"` + Locations []location.SourceLocation `json:"locations"` + Path []interface{} `json:"path,omitempty"` + Extensions map[string]interface{} `json:"extensions,omitempty"` + originalError error +} + +func (g FormattedError) OriginalError() error { + return g.originalError } func (g FormattedError) Error() string { @@ -33,9 +38,10 @@ func FormatError(err error) FormattedError { return err case *Error: ret := FormattedError{ - Message: err.Error(), - Locations: err.Locations, - Path: err.Path, + Message: err.Error(), + Locations: err.Locations, + Path: err.Path, + originalError: err, } if err := err.OriginalError; err != nil { if extended, ok := err.(ExtendedError); ok { From bfe0f60e87da059bcaf73bc01c6fe6205439a0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Ram=C3=B3n?= Date: Tue, 27 Nov 2018 23:16:45 -0500 Subject: [PATCH 2/3] adds OriginalError support --- abstract_test.go | 35 ++-- executor_test.go | 47 ++--- gqlerrors/formatted.go | 2 +- lists_test.go | 384 ++++++++++++++++++++-------------- nonnull_test.go | 458 ++++++++++++++++++++++++++--------------- 5 files changed, 565 insertions(+), 361 deletions(-) diff --git a/abstract_test.go b/abstract_test.go index 4b169f90..853ae911 100644 --- a/abstract_test.go +++ b/abstract_test.go @@ -491,6 +491,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) { } }` + originalError := gqlerrors.NewFormattedError(`Runtime Object type "Human" is not a possible type for "Pet".`) expected := &graphql.Result{ Data: map[string]interface{}{ "pets": []interface{}{ @@ -505,27 +506,27 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) { nil, }, }, - Errors: []gqlerrors.FormattedError{ - { - Message: `Runtime Object type "Human" is not a possible type for "Pet".`, - Locations: []location.SourceLocation{ - { - Line: 2, - Column: 7, - }, - }, - Path: []interface{}{ - "pets", - 2, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: []location.SourceLocation{ + { + Line: 2, + Column: 7, }, }, - }, + Path: []interface{}{ + "pets", + 2, + }, + OriginalError: originalError, + })}, } result := graphql.Do(graphql.Params{ Schema: schema, RequestString: query, }) + if len(result.Errors) == 0 { t.Fatalf("wrong result, expected errors: %v, got: %v", len(expected.Errors), len(result.Errors)) } @@ -618,6 +619,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) { } }` + originalError := gqlerrors.NewFormattedError(`Runtime Object type "Human" is not a possible type for "Pet".`) expected := &graphql.Result{ Data: map[string]interface{}{ "pets": []interface{}{ @@ -633,8 +635,8 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) { }, }, Errors: []gqlerrors.FormattedError{ - { - Message: `Runtime Object type "Human" is not a possible type for "Pet".`, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, Locations: []location.SourceLocation{ { Line: 2, @@ -645,7 +647,8 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) { "pets", 2, }, - }, + OriginalError: originalError, + }), }, } diff --git a/executor_test.go b/executor_test.go index 71e3b262..7b5779bc 100644 --- a/executor_test.go +++ b/executor_test.go @@ -515,18 +515,19 @@ func TestNullsOutErrorSubtrees(t *testing.T) { "sync": "sync", "syncError": nil, } - expectedErrors := []gqlerrors.FormattedError{ - { - Message: "Error getting syncError", - Locations: []location.SourceLocation{ - { - Line: 3, Column: 7, - }, - }, - Path: []interface{}{ - "syncError", + originalError := errors.New("Error getting syncError") + expectedErrors := []gqlerrors.FormattedError{gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), + Locations: []location.SourceLocation{ + { + Line: 3, Column: 7, }, }, + Path: []interface{}{ + "syncError", + }, + OriginalError: originalError, + }), } data := map[string]interface{}{ @@ -1296,6 +1297,7 @@ func TestFailsWhenAnIsTypeOfCheckIsNotMet(t *testing.T) { }, } + originalError := gqlerrors.NewFormattedError(`Expected value of type "SpecialType" but got: graphql_test.testNotSpecialType.`) expected := &graphql.Result{ Data: map[string]interface{}{ "specials": []interface{}{ @@ -1305,21 +1307,20 @@ func TestFailsWhenAnIsTypeOfCheckIsNotMet(t *testing.T) { nil, }, }, - Errors: []gqlerrors.FormattedError{ - { - Message: `Expected value of type "SpecialType" but got: graphql_test.testNotSpecialType.`, - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 3, - }, - }, - Path: []interface{}{ - "specials", - 1, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 3, }, }, - }, + Path: []interface{}{ + "specials", + 1, + }, + OriginalError: originalError, + })}, } specialType := graphql.NewObject(graphql.ObjectConfig{ diff --git a/gqlerrors/formatted.go b/gqlerrors/formatted.go index 48d7c060..bc0dfff4 100644 --- a/gqlerrors/formatted.go +++ b/gqlerrors/formatted.go @@ -41,7 +41,7 @@ func FormatError(err error) FormattedError { Message: err.Error(), Locations: err.Locations, Path: err.Path, - originalError: err, + originalError: err.OriginalError, } if err := err.OriginalError; err != nil { if extended, ok := err.(ExtendedError); ok { diff --git a/lists_test.go b/lists_test.go index 9d9c6bb5..155f898a 100644 --- a/lists_test.go +++ b/lists_test.go @@ -1,6 +1,7 @@ package graphql_test import ( + "errors" "reflect" "testing" @@ -252,24 +253,32 @@ func TestLists_NonNullListOfNullableObjectsContainsNull(t *testing.T) { } func TestLists_NonNullListOfNullableObjectsReturnsNull(t *testing.T) { ttype := graphql.NewNonNull(graphql.NewList(graphql.Int)) + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, nil, expected) @@ -326,24 +335,32 @@ func TestLists_NonNullListOfNullableFunc_ReturnsNull(t *testing.T) { data := func() interface{} { return nil } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -424,27 +441,35 @@ func TestLists_NullableListOfNonNullObjects_ContainsNull(t *testing.T) { data := []interface{}{ 1, nil, 2, } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + 1, + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": map[string]interface{}{ "test": nil, }, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - 1, - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -494,27 +519,35 @@ func TestLists_NullableListOfNonNullFunc_ContainsNull(t *testing.T) { 1, nil, 2, } } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + 1, + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": map[string]interface{}{ "test": nil, }, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - 1, - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -578,6 +611,22 @@ func TestLists_NullableListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) { return 2, nil }, } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + 1, + }, + OriginalError: rootError, + }) expected := &graphql.Result{ /* // TODO: Because thunks are called after the result map has been assembled, @@ -591,21 +640,13 @@ func TestLists_NullableListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) { }, */ Data: nil, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - 1, - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -633,50 +674,65 @@ func TestLists_NonNullListOfNonNullObjects_ContainsNull(t *testing.T) { data := []interface{}{ 1, nil, 2, } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + 1, + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - 1, - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) } func TestLists_NonNullListOfNonNullObjects_ReturnsNull(t *testing.T) { ttype := graphql.NewNonNull(graphql.NewList(graphql.NewNonNull(graphql.Int))) - + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, nil, expected) @@ -714,25 +770,33 @@ func TestLists_NonNullListOfNonNullFunc_ContainsNull(t *testing.T) { 1, nil, 2, } } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + 1, + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - 1, - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -745,24 +809,32 @@ func TestLists_NonNullListOfNonNullFunc_ReturnsNull(t *testing.T) { data := func() interface{} { return nil } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -809,6 +881,22 @@ func TestLists_NonNullListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) { return 2, nil }, } + rootError := errors.New("Cannot return null for non-nullable field DataType.test.") + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + { + Line: 1, + Column: 10, + }, + }, + Path: []interface{}{ + "nest", + "test", + 1, + }, + OriginalError: rootError, + }) expected := &graphql.Result{ /* // TODO: Because thunks are called after the result map has been assembled, @@ -820,21 +908,13 @@ func TestLists_NonNullListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) { }, */ Data: nil, - Errors: []gqlerrors.FormattedError{ - { - Message: "Cannot return null for non-nullable field DataType.test.", - Locations: []location.SourceLocation{ - { - Line: 1, - Column: 10, - }, - }, - Path: []interface{}{ - "nest", - "test", - 1, - }, - }, + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) @@ -843,15 +923,16 @@ func TestLists_NonNullListOfNonNullArrayOfFunc_ContainsNulls(t *testing.T) { func TestLists_UserErrorExpectIterableButDidNotGetOne(t *testing.T) { ttype := graphql.NewList(graphql.Int) data := "Not an iterable" + originalError := gqlerrors.NewFormattedError("User Error: expected iterable, but did not find one for field DataType.test.") expected := &graphql.Result{ Data: map[string]interface{}{ "nest": map[string]interface{}{ "test": nil, }, }, - Errors: []gqlerrors.FormattedError{ - { - Message: "User Error: expected iterable, but did not find one for field DataType.test.", + Errors: []gqlerrors.FormattedError{gqlerrors.FormatError( + gqlerrors.Error{ + Message: originalError.Message, Locations: []location.SourceLocation{ { Line: 1, @@ -862,7 +943,8 @@ func TestLists_UserErrorExpectIterableButDidNotGetOne(t *testing.T) { "nest", "test", }, - }, + OriginalError: originalError, + }), }, } checkList(t, ttype, data, expected) diff --git a/nonnull_test.go b/nonnull_test.go index 407636c8..0003a99d 100644 --- a/nonnull_test.go +++ b/nonnull_test.go @@ -1,6 +1,8 @@ package graphql_test import ( + "errors" + "fmt" "reflect" "sort" "testing" @@ -9,6 +11,7 @@ import ( "github.com/graphql-go/graphql/gqlerrors" "github.com/graphql-go/graphql/language/location" "github.com/graphql-go/graphql/testutil" + "github.com/kr/pretty" ) var syncError = "sync" @@ -116,13 +119,14 @@ func TestNonNull_NullsANullableFieldThatThrowsSynchronously(t *testing.T) { sync } ` + originalError := errors.New(syncError) expected := &graphql.Result{ Data: map[string]interface{}{ "sync": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: syncError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ { Line: 3, Column: 9, @@ -131,7 +135,8 @@ func TestNonNull_NullsANullableFieldThatThrowsSynchronously(t *testing.T) { Path: []interface{}{ "sync", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -147,6 +152,7 @@ func TestNonNull_NullsANullableFieldThatThrowsSynchronously(t *testing.T) { if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } + fmt.Printf("%v\n", pretty.Diff(expected, result)) if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } @@ -157,13 +163,14 @@ func TestNonNull_NullsANullableFieldThatThrowsInAPromise(t *testing.T) { promise } ` + originalError := errors.New(promiseError) expected := &graphql.Result{ Data: map[string]interface{}{ "promise": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: promiseError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ { Line: 3, Column: 9, @@ -172,7 +179,8 @@ func TestNonNull_NullsANullableFieldThatThrowsInAPromise(t *testing.T) { Path: []interface{}{ "promise", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -200,13 +208,14 @@ func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANullableFieldThat } } ` + originalError := errors.New(nonNullSyncError) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullSyncError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ { Line: 4, Column: 11, @@ -216,7 +225,8 @@ func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANullableFieldThat "nest", "nonNullSync", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -244,13 +254,14 @@ func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldT } } ` + originalError := errors.New(nonNullPromiseError) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullPromiseError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ { Line: 4, Column: 11, @@ -260,7 +271,8 @@ func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldT "nest", "nonNullPromise", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -288,13 +300,14 @@ func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldTha } } ` + originalError := errors.New(nonNullSyncError) expected := &graphql.Result{ Data: map[string]interface{}{ "promiseNest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullSyncError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ { Line: 4, Column: 11, @@ -304,7 +317,8 @@ func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldTha "promiseNest", "nonNullSync", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -332,13 +346,14 @@ func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldTha } } ` + originalError := errors.New(nonNullPromiseError) expected := &graphql.Result{ Data: map[string]interface{}{ "promiseNest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullPromiseError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ { Line: 4, Column: 11, @@ -348,7 +363,8 @@ func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldTha "promiseNest", "nonNullPromise", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -398,6 +414,8 @@ func TestNonNull_NullsAComplexTreeOfNullableFieldsThatThrow(t *testing.T) { } } ` + syncOriginalError := errors.New(syncError) + promiseOriginalError := errors.New(promiseError) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": map[string]interface{}{ @@ -426,114 +444,126 @@ func TestNonNull_NullsAComplexTreeOfNullableFieldsThatThrow(t *testing.T) { }, }, Errors: []gqlerrors.FormattedError{ - { - Message: syncError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: syncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 4, Column: 11}, }, Path: []interface{}{ "nest", "sync", }, - }, - { - Message: syncError, + OriginalError: syncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: syncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 7, Column: 13}, }, Path: []interface{}{ "nest", "nest", "sync", }, - }, - { - Message: syncError, + OriginalError: syncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: syncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 11, Column: 13}, }, Path: []interface{}{ "nest", "promiseNest", "sync", }, - }, - { - Message: syncError, + OriginalError: syncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: syncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 16, Column: 11}, }, Path: []interface{}{ "promiseNest", "sync", }, - }, - { - Message: syncError, + OriginalError: syncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: syncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 19, Column: 13}, }, Path: []interface{}{ "promiseNest", "nest", "sync", }, - }, - { - Message: syncError, + OriginalError: syncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: syncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 23, Column: 13}, }, Path: []interface{}{ "promiseNest", "promiseNest", "sync", }, - }, - { - Message: promiseError, + OriginalError: syncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: promiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 5, Column: 11}, }, Path: []interface{}{ "nest", "promise", }, - }, - { - Message: promiseError, + OriginalError: promiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: promiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 8, Column: 13}, }, Path: []interface{}{ "nest", "nest", "promise", }, - }, - { - Message: promiseError, + OriginalError: promiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: promiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 12, Column: 13}, }, Path: []interface{}{ "nest", "promiseNest", "promise", }, - }, - { - Message: promiseError, + OriginalError: promiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: promiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 17, Column: 11}, }, Path: []interface{}{ "promiseNest", "promise", }, - }, - { - Message: promiseError, + OriginalError: promiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: promiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 20, Column: 13}, }, Path: []interface{}{ "promiseNest", "nest", "promise", }, - }, - { - Message: promiseError, + OriginalError: promiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: promiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 24, Column: 13}, }, Path: []interface{}{ "promiseNest", "promiseNest", "promise", }, - }, + OriginalError: promiseOriginalError, + }), }, } // parse query @@ -607,6 +637,8 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfField } } ` + nonNullSyncOriginalError := errors.New(nonNullSyncError) + onNullPromiseOriginalError := errors.New(nonNullPromiseError) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, @@ -615,8 +647,8 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfField "anotherPromiseNest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullSyncError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullSyncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 8, Column: 19}, }, @@ -624,9 +656,10 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfField "nest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullSync", }, - }, - { - Message: nonNullSyncError, + OriginalError: nonNullSyncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullSyncOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 19, Column: 19}, }, @@ -634,9 +667,10 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfField "promiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullSync", }, - }, - { - Message: nonNullPromiseError, + OriginalError: nonNullSyncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: onNullPromiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 30, Column: 19}, }, @@ -644,9 +678,10 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfField "anotherNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullPromise", }, - }, - { - Message: nonNullPromiseError, + OriginalError: onNullPromiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: onNullPromiseOriginalError.Error(), Locations: []location.SourceLocation{ {Line: 41, Column: 19}, }, @@ -654,7 +689,8 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldThrowsInALongChainOfField "anotherPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullPromise", }, - }, + OriginalError: onNullPromiseOriginalError, + }), }, } // parse query @@ -750,21 +786,29 @@ func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldT } } ` + rootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullSync.`) + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + {Line: 4, Column: 11}, + }, + Path: []interface{}{ + "nest", + "nonNullSync", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullSync.`, - Locations: []location.SourceLocation{ - {Line: 4, Column: 11}, - }, - Path: []interface{}{ - "nest", - "nonNullSync", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } // parse query @@ -792,21 +836,29 @@ func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldT } } ` + rootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullPromise.`) + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + {Line: 4, Column: 11}, + }, + Path: []interface{}{ + "nest", + "nonNullPromise", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, - Locations: []location.SourceLocation{ - {Line: 4, Column: 11}, - }, - Path: []interface{}{ - "nest", - "nonNullPromise", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } // parse query @@ -835,21 +887,29 @@ func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldTha } } ` + rootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullSync.`) + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + {Line: 4, Column: 11}, + }, + Path: []interface{}{ + "promiseNest", + "nonNullSync", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "promiseNest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullSync.`, - Locations: []location.SourceLocation{ - {Line: 4, Column: 11}, - }, - Path: []interface{}{ - "promiseNest", - "nonNullSync", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } // parse query @@ -877,21 +937,29 @@ func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldTha } } ` + rootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullPromise.`) + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + {Line: 4, Column: 11}, + }, + Path: []interface{}{ + "promiseNest", + "nonNullPromise", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "promiseNest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, - Locations: []location.SourceLocation{ - {Line: 4, Column: 11}, - }, - Path: []interface{}{ - "promiseNest", - "nonNullPromise", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } // parse query @@ -1037,6 +1105,52 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldReturnsNullInALongChainOf } } ` + nonNullSyncRootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullSync.`) + nonNullSyncOriginalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullSyncRootError.Error(), + Locations: []location.SourceLocation{ + {Line: 8, Column: 19}, + }, + Path: []interface{}{ + "nest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", + "nonNullPromiseNest", "nonNullSync", + }, + OriginalError: nonNullSyncRootError, + }) + nonNullSyncOriginalError2 := gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullSyncRootError.Error(), + Locations: []location.SourceLocation{ + {Line: 19, Column: 19}, + }, + Path: []interface{}{ + "promiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", + "nonNullPromiseNest", "nonNullSync", + }, + OriginalError: nonNullSyncRootError, + }) + nonNullPromiseError := errors.New(`Cannot return null for non-nullable field DataType.nonNullPromise.`) + nonNullPromiseOriginalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullPromiseError.Error(), + Locations: []location.SourceLocation{ + {Line: 30, Column: 19}, + }, + Path: []interface{}{ + "anotherNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", + "nonNullPromiseNest", "nonNullPromise", + }, + OriginalError: nonNullPromiseError, + }) + nonNullPromiseOriginalError2 := gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullPromiseError.Error(), + Locations: []location.SourceLocation{ + {Line: 41, Column: 19}, + }, + Path: []interface{}{ + "anotherPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", + "nonNullPromiseNest", "nonNullPromise", + }, + OriginalError: nonNullPromiseError, + }) expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, @@ -1045,46 +1159,30 @@ func TestNonNull_NullsTheFirstNullableObjectAfterAFieldReturnsNullInALongChainOf "anotherPromiseNest": nil, }, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullSync.`, - Locations: []location.SourceLocation{ - {Line: 8, Column: 19}, - }, - Path: []interface{}{ - "nest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", - "nonNullPromiseNest", "nonNullSync", - }, - }, - { - Message: `Cannot return null for non-nullable field DataType.nonNullSync.`, - Locations: []location.SourceLocation{ - {Line: 19, Column: 19}, - }, - Path: []interface{}{ - "promiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", - "nonNullPromiseNest", "nonNullSync", - }, - }, - { - Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, - Locations: []location.SourceLocation{ - {Line: 30, Column: 19}, - }, - Path: []interface{}{ - "anotherNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", - "nonNullPromiseNest", "nonNullPromise", - }, - }, - { - Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, - Locations: []location.SourceLocation{ - {Line: 41, Column: 19}, - }, - Path: []interface{}{ - "anotherPromiseNest", "nonNullNest", "nonNullPromiseNest", "nonNullNest", - "nonNullPromiseNest", "nonNullPromise", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullSyncOriginalError.Message, + Locations: nonNullSyncOriginalError.Locations, + Path: nonNullSyncOriginalError.Path, + OriginalError: nonNullSyncOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullSyncOriginalError2.Message, + Locations: nonNullSyncOriginalError2.Locations, + Path: nonNullSyncOriginalError2.Path, + OriginalError: nonNullSyncOriginalError2, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullPromiseOriginalError.Message, + Locations: nonNullPromiseOriginalError.Locations, + Path: nonNullPromiseOriginalError.Path, + OriginalError: nonNullPromiseOriginalError, + }), + gqlerrors.FormatError(gqlerrors.Error{ + Message: nonNullPromiseOriginalError2.Message, + Locations: nonNullPromiseOriginalError2.Locations, + Path: nonNullPromiseOriginalError2.Path, + OriginalError: nonNullPromiseOriginalError2, + }), }, } // parse query @@ -1114,18 +1212,20 @@ func TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldThrows(t *testing.T) { doc := ` query Q { nonNullSync } ` + originalError := errors.New(nonNullSyncError) expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullSyncError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ {Line: 2, Column: 17}, }, Path: []interface{}{ "nonNullSync", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -1149,18 +1249,20 @@ func TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldErrors(t *testing.T) { doc := ` query Q { nonNullPromise } ` + originalError := errors.New(nonNullPromiseError) expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ - { - Message: nonNullPromiseError, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Error(), Locations: []location.SourceLocation{ {Line: 2, Column: 17}, }, Path: []interface{}{ "nonNullPromise", }, - }, + OriginalError: originalError, + }), }, } // parse query @@ -1184,18 +1286,26 @@ func TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldReturnsNull(t *testing.T) doc := ` query Q { nonNullSync } ` + rootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullSync.`) + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + {Line: 2, Column: 17}, + }, + Path: []interface{}{ + "nonNullSync", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullSync.`, - Locations: []location.SourceLocation{ - {Line: 2, Column: 17}, - }, - Path: []interface{}{ - "nonNullSync", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } // parse query @@ -1219,18 +1329,26 @@ func TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldResolvesNull(t *testing.T doc := ` query Q { nonNullPromise } ` + rootError := errors.New(`Cannot return null for non-nullable field DataType.nonNullPromise.`) + originalError := gqlerrors.FormatError(gqlerrors.Error{ + Message: rootError.Error(), + Locations: []location.SourceLocation{ + {Line: 2, Column: 17}, + }, + Path: []interface{}{ + "nonNullPromise", + }, + OriginalError: rootError, + }) expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ - { - Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, - Locations: []location.SourceLocation{ - {Line: 2, Column: 17}, - }, - Path: []interface{}{ - "nonNullPromise", - }, - }, + gqlerrors.FormatError(gqlerrors.Error{ + Message: originalError.Message, + Locations: originalError.Locations, + Path: originalError.Path, + OriginalError: originalError, + }), }, } // parse query From 7995f6a8c29e2c9bdaddea77be01be4d340a3d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Ram=C3=B3n?= Date: Sun, 2 Dec 2018 20:18:12 -0500 Subject: [PATCH 3/3] executor: adds OriginalError tests --- executor_test.go | 80 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/executor_test.go b/executor_test.go index 7b5779bc..62d7c682 100644 --- a/executor_test.go +++ b/executor_test.go @@ -2046,7 +2046,7 @@ func (err extendedError) Extensions() map[string]interface{} { var _ gqlerrors.ExtendedError = &extendedError{} -func testErrors(t *testing.T, nameType graphql.Output, extensions map[string]interface{}) *graphql.Result { +func testErrors(t *testing.T, nameType graphql.Output, extensions map[string]interface{}, formatErrorFn func(err error) error) *graphql.Result { type Hero struct { Id string `graphql:"id"` Name string @@ -2073,7 +2073,12 @@ func testErrors(t *testing.T, nameType graphql.Output, extensions map[string]int if hero.Name != "" { return hero.Name, nil } + err := fmt.Errorf("Name for character with ID %v could not be fetched.", hero.Id) + if formatErrorFn != nil { + err = formatErrorFn(err) + } + if extensions != nil { return nil, &extendedError{ error: err, @@ -2134,7 +2139,7 @@ func testErrors(t *testing.T, nameType graphql.Output, extensions map[string]int // http://facebook.github.io/graphql/June2018/#example-bc485 func TestQuery_ErrorPath(t *testing.T) { - result := testErrors(t, graphql.String, nil) + result := testErrors(t, graphql.String, nil, nil) assertJSON(t, `{ "errors": [ @@ -2168,7 +2173,7 @@ func TestQuery_ErrorPath(t *testing.T) { // http://facebook.github.io/graphql/June2018/#example-08b62 func TestQuery_ErrorPathForNonNullField(t *testing.T) { - result := testErrors(t, graphql.NewNonNull(graphql.String), nil) + result := testErrors(t, graphql.NewNonNull(graphql.String), nil, nil) assertJSON(t, `{ "errors": [ @@ -2202,7 +2207,7 @@ func TestQuery_ErrorExtensions(t *testing.T) { result := testErrors(t, graphql.NewNonNull(graphql.String), map[string]interface{}{ "code": "CAN_NOT_FETCH_BY_ID", "timestamp": "Fri Feb 9 14:33:09 UTC 2018", - }) + }, nil) assertJSON(t, `{ "errors": [ @@ -2233,3 +2238,70 @@ func TestQuery_ErrorExtensions(t *testing.T) { } }`, result) } + +func TestQuery_OriginalErrorBuiltin(t *testing.T) { + result := testErrors(t, graphql.String, nil, nil) + originalError := result.Errors[0].OriginalError() + switch originalError.(type) { + case error: + default: + t.Fatalf("unexpected error: %v", reflect.TypeOf(originalError)) + } +} + +func TestQuery_OriginalErrorExtended(t *testing.T) { + result := testErrors(t, graphql.String, map[string]interface{}{ + "code": "CAN_NOT_FETCH_BY_ID", + }, nil) + originalError := result.Errors[0].OriginalError() + switch originalError.(type) { + case *extendedError: + case extendedError: + default: + t.Fatalf("unexpected error: %v", reflect.TypeOf(originalError)) + } +} + +type customError struct { + error +} + +func (e customError) Error() string { + return e.error.Error() +} + +func TestQuery_OriginalErrorCustom(t *testing.T) { + result := testErrors(t, graphql.String, nil, func(err error) error { + return customError{error: err} + }) + originalError := result.Errors[0].OriginalError() + switch originalError.(type) { + case customError: + default: + t.Fatalf("unexpected error: %v", reflect.TypeOf(originalError)) + } +} + +func TestQuery_OriginalErrorCustomPtr(t *testing.T) { + result := testErrors(t, graphql.String, nil, func(err error) error { + return &customError{error: err} + }) + originalError := result.Errors[0].OriginalError() + switch originalError.(type) { + case *customError: + default: + t.Fatalf("unexpected error: %v", reflect.TypeOf(originalError)) + } +} + +func TestQuery_OriginalErrorPanic(t *testing.T) { + result := testErrors(t, graphql.String, nil, func(err error) error { + panic(errors.New("panic error")) + }) + originalError := result.Errors[0].OriginalError() + switch originalError.(type) { + case error: + default: + t.Fatalf("unexpected error: %v", reflect.TypeOf(originalError)) + } +}