@@ -2,6 +2,7 @@ import { expect } from 'chai';
22import { describe , it } from 'mocha' ;
33
44import { expectJSON } from '../../__testUtils__/expectJSON' ;
5+ import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick' ;
56
67import { inspect } from '../../jsutils/inspect' ;
78import { invariant } from '../../jsutils/invariant' ;
@@ -625,6 +626,56 @@ describe('Execute: Handles basic execution tasks', () => {
625626 } ) ;
626627 } ) ;
627628
629+ it ( 'handles sync errors combined with rejections' , async ( ) => {
630+ let isAsyncResolverFinished = false ;
631+
632+ const schema = new GraphQLSchema ( {
633+ query : new GraphQLObjectType ( {
634+ name : 'Query' ,
635+ fields : {
636+ syncNullError : {
637+ type : new GraphQLNonNull ( GraphQLString ) ,
638+ resolve : ( ) => null ,
639+ } ,
640+ asyncNullError : {
641+ type : new GraphQLNonNull ( GraphQLString ) ,
642+ async resolve ( ) {
643+ await resolveOnNextTick ( ) ;
644+ await resolveOnNextTick ( ) ;
645+ await resolveOnNextTick ( ) ;
646+ isAsyncResolverFinished = true ;
647+ return null ;
648+ } ,
649+ } ,
650+ } ,
651+ } ) ,
652+ } ) ;
653+
654+ // Order is important here, as the promise has to be created before the synchronous error is thrown
655+ const document = parse ( `
656+ {
657+ asyncNullError
658+ syncNullError
659+ }
660+ ` ) ;
661+
662+ const result = execute ( { schema, document } ) ;
663+
664+ expect ( isAsyncResolverFinished ) . to . equal ( false ) ;
665+ expectJSON ( await result ) . toDeepEqual ( {
666+ data : null ,
667+ errors : [
668+ {
669+ message :
670+ 'Cannot return null for non-nullable field Query.syncNullError.' ,
671+ locations : [ { line : 4 , column : 9 } ] ,
672+ path : [ 'syncNullError' ] ,
673+ } ,
674+ ] ,
675+ } ) ;
676+ expect ( isAsyncResolverFinished ) . to . equal ( true ) ;
677+ } ) ;
678+
628679 it ( 'Full response path is included for non-nullable fields' , ( ) => {
629680 const A : GraphQLObjectType = new GraphQLObjectType ( {
630681 name : 'A' ,
0 commit comments