@@ -2,6 +2,7 @@ import { assert, expect } from 'chai';
2
2
import { describe , it } from 'mocha' ;
3
3
4
4
import { expectJSON } from '../../__testUtils__/expectJSON.js' ;
5
+ import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick.js' ;
5
6
6
7
import { inspect } from '../../jsutils/inspect.js' ;
7
8
@@ -580,6 +581,56 @@ describe('Execute: Handles basic execution tasks', () => {
580
581
} ) ;
581
582
} ) ;
582
583
584
+ it ( 'handles sync errors combined with rejections' , async ( ) => {
585
+ let isAsyncResolverFinished = false ;
586
+
587
+ const schema = new GraphQLSchema ( {
588
+ query : new GraphQLObjectType ( {
589
+ name : 'Query' ,
590
+ fields : {
591
+ syncNullError : {
592
+ type : new GraphQLNonNull ( GraphQLString ) ,
593
+ resolve : ( ) => null ,
594
+ } ,
595
+ asyncNullError : {
596
+ type : new GraphQLNonNull ( GraphQLString ) ,
597
+ async resolve ( ) {
598
+ await resolveOnNextTick ( ) ;
599
+ await resolveOnNextTick ( ) ;
600
+ await resolveOnNextTick ( ) ;
601
+ isAsyncResolverFinished = true ;
602
+ return null ;
603
+ } ,
604
+ } ,
605
+ } ,
606
+ } ) ,
607
+ } ) ;
608
+
609
+ // Order is important here, as the promise has to be created before the synchronous error is thrown
610
+ const document = parse ( `
611
+ {
612
+ asyncNullError
613
+ syncNullError
614
+ }
615
+ ` ) ;
616
+
617
+ const result = execute ( { schema, document } ) ;
618
+
619
+ expect ( isAsyncResolverFinished ) . to . equal ( false ) ;
620
+ expectJSON ( await result ) . toDeepEqual ( {
621
+ data : null ,
622
+ errors : [
623
+ {
624
+ message :
625
+ 'Cannot return null for non-nullable field Query.syncNullError.' ,
626
+ locations : [ { line : 4 , column : 9 } ] ,
627
+ path : [ 'syncNullError' ] ,
628
+ } ,
629
+ ] ,
630
+ } ) ;
631
+ expect ( isAsyncResolverFinished ) . to . equal ( true ) ;
632
+ } ) ;
633
+
583
634
it ( 'Full response path is included for non-nullable fields' , ( ) => {
584
635
const A : GraphQLObjectType = new GraphQLObjectType ( {
585
636
name : 'A' ,
0 commit comments