diff --git a/executor.go b/executor.go index 93ec30e8..d8477140 100644 --- a/executor.go +++ b/executor.go @@ -46,21 +46,18 @@ func Execute(p ExecuteParams) (result *Result) { addExtensionResults(&p, result) }() - resultChannel := make(chan *Result) - result = &Result{ - Extensions: map[string]interface{}{}, - } + resultChannel := make(chan *Result, 2) + + go func() { + result := &Result{} - go func(out chan<- *Result, done <-chan struct{}) { defer func() { if err := recover(); err != nil { - result.AppendErrors(gqlerrors.FormatError(err.(error))) - } - select { - case out <- result: - case <-done: + result.Errors = append(result.Errors, gqlerrors.FormatError(err.(error))) } + resultChannel <- result }() + exeContext, err := buildExecutionContext(buildExecutionCtxParams{ Schema: p.Schema, Root: p.Root, @@ -72,26 +69,26 @@ func Execute(p ExecuteParams) (result *Result) { }) if err != nil { - result.AppendErrors(gqlerrors.FormatError(err)) + result.Errors = append(result.Errors, gqlerrors.FormatError(err.(error))) + resultChannel <- result return } - result = executeOperation(executeOperationParams{ + resultChannel <- executeOperation(executeOperationParams{ ExecutionContext: exeContext, Root: p.Root, Operation: exeContext.Operation, }) - - }(resultChannel, ctx.Done()) + }() select { case <-ctx.Done(): - result.AppendErrors(gqlerrors.FormatError(ctx.Err())) + result := &Result{} + result.Errors = append(result.Errors, gqlerrors.FormatError(ctx.Err())) + return result case r := <-resultChannel: - result = r + return r } - - return } type buildExecutionCtxParams struct { diff --git a/extensions.go b/extensions.go index 8dd6f345..1c448fbf 100644 --- a/extensions.go +++ b/extensions.go @@ -236,7 +236,7 @@ func addExtensionResults(p *ExecuteParams, result *Result) { func() { defer func() { if r := recover(); r != nil { - result.AppendErrors(gqlerrors.FormatError(fmt.Errorf("%s.GetResult: %v", ext.Name(), r.(error)))) + result.Errors = append(result.Errors, gqlerrors.FormatError(fmt.Errorf("%s.GetResult: %v", ext.Name(), r.(error)))) } }() if ext.HasResult() { diff --git a/types.go b/types.go index b4a58047..5b991d8c 100644 --- a/types.go +++ b/types.go @@ -1,8 +1,6 @@ package graphql import ( - "sync" - "github.com/graphql-go/graphql/gqlerrors" ) @@ -13,19 +11,9 @@ type Result struct { Data interface{} `json:"data"` Errors []gqlerrors.FormattedError `json:"errors,omitempty"` Extensions map[string]interface{} `json:"extensions,omitempty"` - - errorsLock sync.Mutex } // HasErrors just a simple function to help you decide if the result has errors or not func (r *Result) HasErrors() bool { return len(r.Errors) > 0 } - -// AppendErrors is the thread-safe way to append error(s) to Result.Errors. -func (r *Result) AppendErrors(errs ...gqlerrors.FormattedError) { - r.errorsLock.Lock() - defer r.errorsLock.Unlock() - - r.Errors = append(r.Errors, errs...) -}