Skip to content

Commit d25cf40

Browse files
committed
correctly handle promises returned by completeValue in async iterable resovlers
# Conflicts: # src/execution/execute.js
1 parent 4cf7098 commit d25cf40

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

src/execution/__tests__/lists-test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

44
import { parse } from '../../language/parser';
5+
import { GraphQLList, GraphQLObjectType } from '../../type/definition';
6+
import { GraphQLString } from '../../type/scalars';
7+
import { GraphQLSchema } from '../../type/schema';
58

69
import { buildSchema } from '../../utilities/buildASTSchema';
710

@@ -73,6 +76,38 @@ describe('Execute: Accepts async iterables as list value', () => {
7376
});
7477
}
7578

79+
function completeObjectList(resolve) {
80+
const schema = new GraphQLSchema({
81+
query: new GraphQLObjectType({
82+
name: 'Query',
83+
fields: {
84+
listField: {
85+
resolve: async function* listField() {
86+
yield await { index: 0 };
87+
yield await { index: 1 };
88+
yield await { index: 2 };
89+
},
90+
type: new GraphQLList(
91+
new GraphQLObjectType({
92+
name: 'ObjectWrapper',
93+
fields: {
94+
index: {
95+
type: GraphQLString,
96+
resolve,
97+
},
98+
},
99+
}),
100+
),
101+
},
102+
},
103+
}),
104+
});
105+
return execute({
106+
schema,
107+
document: parse('{ listField { index } }'),
108+
});
109+
}
110+
76111
it('Accepts an AsyncGenerator function as a List value', async () => {
77112
async function* listField() {
78113
yield await 'two';
@@ -121,6 +156,34 @@ describe('Execute: Accepts async iterables as list value', () => {
121156
],
122157
});
123158
});
159+
160+
it('Handles promises from `completeValue` in AsyncIterables', async () => {
161+
expect(
162+
await completeObjectList(({ index }) => Promise.resolve(index)),
163+
).to.deep.equal({
164+
data: { listField: [{ index: '0' }, { index: '1' }, { index: '2' }] },
165+
});
166+
});
167+
168+
it('Handles rejected promises from `completeValue` in AsyncIterables', async () => {
169+
expect(
170+
await completeObjectList(({ index }) => {
171+
if (index === 2) {
172+
return Promise.reject(new Error('bad'));
173+
}
174+
return Promise.resolve(index);
175+
}),
176+
).to.deep.equal({
177+
data: { listField: [{ index: '0' }, { index: '1' }, { index: null }] },
178+
errors: [
179+
{
180+
message: 'bad',
181+
locations: [{ line: 1, column: 15 }],
182+
path: ['listField', 2, 'index'],
183+
},
184+
],
185+
});
186+
});
124187
});
125188

126189
describe('Execute: Handles list nullability', () => {

src/execution/execute.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,7 @@ function completeAsyncIteratorValue(
869869
path: Path,
870870
iterator: AsyncIterator<mixed>,
871871
): Promise<$ReadOnlyArray<mixed>> {
872+
let containsPromise = false;
872873
return new Promise((resolve) => {
873874
function next(index, completedResults) {
874875
const fieldPath = addPath(path, index, undefined);
@@ -880,16 +881,18 @@ function completeAsyncIteratorValue(
880881
}
881882
// TODO can the error checking logic be consolidated with completeListValue?
882883
try {
883-
completedResults.push(
884-
completeValue(
885-
exeContext,
886-
itemType,
887-
fieldNodes,
888-
info,
889-
fieldPath,
890-
value,
891-
),
884+
const completedItem = completeValue(
885+
exeContext,
886+
itemType,
887+
fieldNodes,
888+
info,
889+
fieldPath,
890+
value,
892891
);
892+
if (isPromise(completedItem)) {
893+
containsPromise = true;
894+
}
895+
completedResults.push(completedItem);
893896
} catch (rawError) {
894897
completedResults.push(null);
895898
const error = locatedError(
@@ -917,7 +920,9 @@ function completeAsyncIteratorValue(
917920
);
918921
}
919922
next(0, []);
920-
});
923+
}).then((completedResults) =>
924+
containsPromise ? Promise.all(completedResults) : completedResults,
925+
);
921926
}
922927

923928
/**

0 commit comments

Comments
 (0)