Skip to content

Commit 04a94fb

Browse files
committed
fix(incrementalDelivery): add additional tests
When a non-null list is streamed and completeValue for a list item fails, the error should bubble up to the list itself and no further payloads should be sent. Addition of tests within this change demonstrates that this is currently the case only when the field resolver for the list returns an iterable, but not when it returns an async iterable. In the latter case, the null correctly bubbles to the list itself for the given payload (`items: null` rather than `items: [null`), but further payloads are sent.
1 parent 90774d7 commit 04a94fb

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

src/execution/__tests__/stream-test.ts

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { assert } from 'chai';
1+
import { assert, expect } from 'chai';
22
import { describe, it } from 'mocha';
33

44
import { expectJSON } from '../../__testUtils__/expectJSON.js';
@@ -851,6 +851,57 @@ describe('Execute: stream directive', () => {
851851
]);
852852
});
853853
it('Handles async errors thrown by completeValue after initialCount is reached', async () => {
854+
const document = parse(`
855+
query {
856+
friendList @stream(initialCount: 1) {
857+
nonNullName
858+
}
859+
}
860+
`);
861+
const result = await complete(document, {
862+
friendList: () => [
863+
Promise.resolve({ nonNullName: friends[0].name }),
864+
Promise.resolve({
865+
nonNullName: () => Promise.reject(new Error('Oops')),
866+
}),
867+
Promise.resolve({ nonNullName: friends[1].name }),
868+
],
869+
});
870+
expectJSON(result).toDeepEqual([
871+
{
872+
data: {
873+
friendList: [{ nonNullName: 'Luke' }],
874+
},
875+
hasNext: true,
876+
},
877+
{
878+
incremental: [
879+
{
880+
items: [null],
881+
path: ['friendList', 1],
882+
errors: [
883+
{
884+
message: 'Oops',
885+
locations: [{ line: 4, column: 11 }],
886+
path: ['friendList', 1, 'nonNullName'],
887+
},
888+
],
889+
},
890+
],
891+
hasNext: true,
892+
},
893+
{
894+
incremental: [
895+
{
896+
items: [{ nonNullName: 'Han' }],
897+
path: ['friendList', 2],
898+
},
899+
],
900+
hasNext: false,
901+
},
902+
]);
903+
});
904+
it('Handles async errors thrown by completeValue after initialCount is reached for a non-nullable list', async () => {
854905
const document = parse(`
855906
query {
856907
nonNullFriendList @stream(initialCount: 1) {
@@ -946,6 +997,50 @@ describe('Execute: stream directive', () => {
946997
},
947998
]);
948999
});
1000+
it('Handles async errors thrown by completeValue after initialCount is reached from async iterable for a non-nullable list', async () => {
1001+
const document = parse(`
1002+
query {
1003+
nonNullFriendList @stream(initialCount: 1) {
1004+
nonNullName
1005+
}
1006+
}
1007+
`);
1008+
const result = await complete(document, {
1009+
async *nonNullFriendList() {
1010+
yield await Promise.resolve({ nonNullName: friends[0].name });
1011+
yield await Promise.resolve({
1012+
nonNullName: () => Promise.reject(new Error('Oops')),
1013+
});
1014+
yield await Promise.resolve({
1015+
nonNullName: friends[1].name,
1016+
}); /* c8 ignore start */
1017+
} /* c8 ignore stop */,
1018+
});
1019+
expectJSON(result).toDeepEqual([
1020+
{
1021+
data: {
1022+
nonNullFriendList: [{ nonNullName: 'Luke' }],
1023+
},
1024+
hasNext: true,
1025+
},
1026+
{
1027+
incremental: [
1028+
{
1029+
items: null,
1030+
path: ['nonNullFriendList', 1],
1031+
errors: [
1032+
{
1033+
message: 'Oops',
1034+
locations: [{ line: 4, column: 11 }],
1035+
path: ['nonNullFriendList', 1, 'nonNullName'],
1036+
},
1037+
],
1038+
},
1039+
],
1040+
hasNext: false,
1041+
},
1042+
]);
1043+
});
9491044
it('Filters payloads that are nulled', async () => {
9501045
const document = parse(`
9511046
query {

0 commit comments

Comments
 (0)