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
42 changes: 42 additions & 0 deletions src/execution/__tests__/defer-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const friendType = new GraphQLObjectType({
fields: {
id: { type: GraphQLID },
name: { type: GraphQLString },
promiseNonNullErrorField: {
type: new GraphQLNonNull(GraphQLString),
resolve: () => Promise.resolve(null),
},
},
name: 'Friend',
});
Expand Down Expand Up @@ -65,6 +69,12 @@ const heroType = new GraphQLObjectType({
type: new GraphQLList(friendType),
resolve: () => friends,
},
asyncFriends: {
type: new GraphQLList(friendType),
async *resolve() {
yield await Promise.resolve(friends[0]);
},
},
},
name: 'Hero',
});
Expand Down Expand Up @@ -657,6 +667,38 @@ describe('Execute: defer directive', () => {
]);
});

it('Filters deferred payloads when a list item returned by an async iterable is nulled', async () => {
const document = parse(`
query {
hero {
asyncFriends {
promiseNonNullErrorField
...NameFragment @defer
}
}
}
fragment NameFragment on Friend {
name
}
`);
const result = await complete(document);
expectJSON(result).toDeepEqual({
data: {
hero: {
asyncFriends: [null],
},
},
errors: [
{
message:
'Cannot return null for non-nullable field Friend.promiseNonNullErrorField.',
locations: [{ line: 5, column: 11 }],
path: ['hero', 'asyncFriends', 0, 'promiseNonNullErrorField'],
},
],
});
});

it('original execute function throws error if anything is deferred and everything else is sync', () => {
const doc = `
query Deferred {
Expand Down
2 changes: 2 additions & 0 deletions src/execution/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,7 @@ async function completeAsyncIteratorValue(
pathToArray(fieldPath),
);
const handledError = handleFieldError(error, itemType, errors);
filterSubsequentPayloads(exeContext, fieldPath);
return handledError;
}),
);
Expand All @@ -1040,6 +1041,7 @@ async function completeAsyncIteratorValue(
fieldNodes,
pathToArray(fieldPath),
);
filterSubsequentPayloads(exeContext, fieldPath);
handleFieldError(error, itemType, errors);
}
} catch (rawError) {
Expand Down