Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2470,3 +2470,98 @@ func TestQuery_NestedJoinedErrors(t *testing.T) {
}
}
}

type pathError struct {
msg string
path []interface{}
}

func (e *pathError) Error() string { return e.msg }
func (e *pathError) Path() []interface{} { return e.path }

func TestQuery_CustomPathError(t *testing.T) {
customPath := []interface{}{"custom", "path", "to", "field"}
result := testErrors(t, graphql.String, nil, func(err error) error {
return &pathError{msg: err.Error(), path: customPath}
})

if len(result.Errors) != 1 {
t.Fatalf("expected 1 error, got %d: %+v", len(result.Errors), result.Errors)
}

if !reflect.DeepEqual(result.Errors[0].Path, customPath) {
t.Errorf("expected path %v, got %v", customPath, result.Errors[0].Path)
}
}

type pathAndExtendedError struct {
msg string
path []interface{}
extensions map[string]interface{}
}

func (e *pathAndExtendedError) Error() string { return e.msg }
func (e *pathAndExtendedError) Path() []interface{} { return e.path }
func (e *pathAndExtendedError) Extensions() map[string]interface{} { return e.extensions }

func TestQuery_PathErrorWithExtensions(t *testing.T) {
customPath := []interface{}{"input", "name"}
customExtensions := map[string]interface{}{"code": "VALIDATION_ERROR"}

result := testErrors(t, graphql.String, nil, func(err error) error {
return &pathAndExtendedError{
msg: err.Error(),
path: customPath,
extensions: customExtensions,
}
})

if len(result.Errors) != 1 {
t.Fatalf("expected 1 error, got %d: %+v", len(result.Errors), result.Errors)
}

if !reflect.DeepEqual(result.Errors[0].Path, customPath) {
t.Errorf("expected path %v, got %v", customPath, result.Errors[0].Path)
}

if !reflect.DeepEqual(result.Errors[0].Extensions, customExtensions) {
t.Errorf("expected extensions %v, got %v", customExtensions, result.Errors[0].Extensions)
}
}

func TestQuery_MultipleErrorsWithCustomPaths(t *testing.T) {
path1 := []interface{}{"input", "name"}
path2 := []interface{}{"input", "age"}

result := testErrors(t, graphql.String, nil, func(err error) error {
err1 := &pathError{msg: "name is required", path: path1}
err2 := &pathError{msg: "age must be positive", path: path2}
return errors.Join(err1, err2)
})

if len(result.Errors) != 2 {
t.Fatalf("expected 2 errors, got %d: %+v", len(result.Errors), result.Errors)
}

if !reflect.DeepEqual(result.Errors[0].Path, path1) {
t.Errorf("error[0]: expected path %v, got %v", path1, result.Errors[0].Path)
}

if !reflect.DeepEqual(result.Errors[1].Path, path2) {
t.Errorf("error[1]: expected path %v, got %v", path2, result.Errors[1].Path)
}
}

func TestQuery_PathErrorReturnsNil(t *testing.T) {
result := testErrors(t, graphql.String, nil, func(err error) error {
return &pathError{msg: err.Error(), path: nil}
})

if len(result.Errors) != 1 {
t.Fatalf("expected 1 error, got %d: %+v", len(result.Errors), result.Errors)
}

if result.Errors[0].Path != nil {
t.Errorf("expected path to be nil, got %v", result.Errors[0].Path)
}
}
12 changes: 10 additions & 2 deletions gqlerrors/formatted.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ type ExtendedError interface {
Extensions() map[string]interface{}
}

type PathError interface {
error
Path() []interface{}
Comment thread
haru0017 marked this conversation as resolved.
}

type FormattedError struct {
Message string `json:"message"`
Locations []location.SourceLocation `json:"locations"`
Expand Down Expand Up @@ -43,10 +48,13 @@ func FormatError(err error) FormattedError {
Path: err.Path,
originalError: err,
}
if err := err.OriginalError; err != nil {
if extended, ok := err.(ExtendedError); ok {
if origErr := err.OriginalError; origErr != nil {
if extended, ok := origErr.(ExtendedError); ok {
ret.Extensions = extended.Extensions()
}
if pathErr, ok := origErr.(PathError); ok {
ret.Path = pathErr.Path()
}
}
return ret
case Error:
Expand Down