Skip to content

Commit e691177

Browse files
committed
separate error handling for non-leaf values
1 parent 0005227 commit e691177

File tree

2 files changed

+336
-73
lines changed

2 files changed

+336
-73
lines changed

src/execution/__tests__/stream-test.ts

Lines changed: 182 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,49 @@ describe('Execute: stream directive', () => {
799799
},
800800
]);
801801
});
802+
it('Handles error returned in async iterable after initialCount is reached', async () => {
803+
const document = parse(`
804+
query {
805+
friendList @stream(initialCount: 1) {
806+
name
807+
id
808+
}
809+
}
810+
`);
811+
const result = await complete(document, {
812+
async *friendList() {
813+
yield await Promise.resolve(friends[0]);
814+
yield await Promise.resolve(new Error('bad'));
815+
},
816+
});
817+
expectJSON(result).toDeepEqual([
818+
{
819+
data: {
820+
friendList: [{ name: 'Luke', id: '1' }],
821+
},
822+
hasNext: true,
823+
},
824+
{
825+
incremental: [
826+
{
827+
items: [null],
828+
path: ['friendList', 1],
829+
errors: [
830+
{
831+
message: 'bad',
832+
locations: [{ line: 3, column: 9 }],
833+
path: ['friendList', 1],
834+
},
835+
],
836+
},
837+
],
838+
hasNext: true,
839+
},
840+
{
841+
hasNext: false,
842+
},
843+
]);
844+
});
802845
it('Handles null returned in list items after initialCount is reached', async () => {
803846
const document = parse(`
804847
query {
@@ -949,7 +992,7 @@ describe('Execute: stream directive', () => {
949992
},
950993
]);
951994
});
952-
it('Handles errors thrown by completeValue after initialCount is reached', async () => {
995+
it('Handles errors thrown by leaf value completion after initialCount is reached', async () => {
953996
const document = parse(`
954997
query {
955998
scalarList @stream(initialCount: 1)
@@ -983,7 +1026,41 @@ describe('Execute: stream directive', () => {
9831026
},
9841027
]);
9851028
});
986-
it('Handles async errors thrown by completeValue after initialCount is reached', async () => {
1029+
it('Handles errors returned by leaf value completion after initialCount is reached', async () => {
1030+
const document = parse(`
1031+
query {
1032+
scalarList @stream(initialCount: 1)
1033+
}
1034+
`);
1035+
const result = await complete(document, {
1036+
scalarList: () => [friends[0].name, new Error('Oops')],
1037+
});
1038+
expectJSON(result).toDeepEqual([
1039+
{
1040+
data: {
1041+
scalarList: ['Luke'],
1042+
},
1043+
hasNext: true,
1044+
},
1045+
{
1046+
incremental: [
1047+
{
1048+
items: [null],
1049+
path: ['scalarList', 1],
1050+
errors: [
1051+
{
1052+
message: 'Oops',
1053+
locations: [{ line: 3, column: 9 }],
1054+
path: ['scalarList', 1],
1055+
},
1056+
],
1057+
},
1058+
],
1059+
hasNext: false,
1060+
},
1061+
]);
1062+
});
1063+
it('Handles async errors thrown by leaf value completion after initialCount is reached', async () => {
9871064
const document = parse(`
9881065
query {
9891066
friendList @stream(initialCount: 1) {
@@ -1034,6 +1111,109 @@ describe('Execute: stream directive', () => {
10341111
},
10351112
]);
10361113
});
1114+
it('Handles nested errors thrown by completeValue after initialCount is reached', async () => {
1115+
const document = parse(`
1116+
query {
1117+
friendList @stream(initialCount: 1) {
1118+
nonNullName
1119+
}
1120+
}
1121+
`);
1122+
const result = await complete(document, {
1123+
friendList: () => [
1124+
{ nonNullName: friends[0].name },
1125+
{ nonNullName: new Error('Oops') },
1126+
{ nonNullName: friends[1].name },
1127+
],
1128+
});
1129+
expectJSON(result).toDeepEqual([
1130+
{
1131+
data: {
1132+
friendList: [{ nonNullName: 'Luke' }],
1133+
},
1134+
hasNext: true,
1135+
},
1136+
{
1137+
incremental: [
1138+
{
1139+
items: [null],
1140+
path: ['friendList', 1],
1141+
errors: [
1142+
{
1143+
message: 'Oops',
1144+
locations: [{ line: 4, column: 11 }],
1145+
path: ['friendList', 1, 'nonNullName'],
1146+
},
1147+
],
1148+
},
1149+
],
1150+
hasNext: true,
1151+
},
1152+
{
1153+
incremental: [
1154+
{
1155+
items: [{ nonNullName: 'Han' }],
1156+
path: ['friendList', 2],
1157+
},
1158+
],
1159+
hasNext: false,
1160+
},
1161+
]);
1162+
});
1163+
it('Handles nested errors thrown by completeValue after initialCount is reached from async iterable', async () => {
1164+
const document = parse(`
1165+
query {
1166+
friendList @stream(initialCount: 1) {
1167+
nonNullName
1168+
}
1169+
}
1170+
`);
1171+
const result = await complete(document, {
1172+
async *friendList() {
1173+
yield await Promise.resolve({ nonNullName: friends[0].name });
1174+
yield await Promise.resolve({
1175+
nonNullName: () => new Error('Oops'),
1176+
});
1177+
yield await Promise.resolve({ nonNullName: friends[1].name });
1178+
},
1179+
});
1180+
expectJSON(result).toDeepEqual([
1181+
{
1182+
data: {
1183+
friendList: [{ nonNullName: 'Luke' }],
1184+
},
1185+
hasNext: true,
1186+
},
1187+
{
1188+
incremental: [
1189+
{
1190+
items: [null],
1191+
path: ['friendList', 1],
1192+
errors: [
1193+
{
1194+
message: 'Oops',
1195+
locations: [{ line: 4, column: 11 }],
1196+
path: ['friendList', 1, 'nonNullName'],
1197+
},
1198+
],
1199+
},
1200+
],
1201+
hasNext: true,
1202+
},
1203+
{
1204+
incremental: [
1205+
{
1206+
items: [{ nonNullName: 'Han' }],
1207+
path: ['friendList', 2],
1208+
},
1209+
],
1210+
hasNext: true,
1211+
},
1212+
{
1213+
hasNext: false,
1214+
},
1215+
]);
1216+
});
10371217
it('Handles nested async errors thrown by completeValue after initialCount is reached', async () => {
10381218
const document = parse(`
10391219
query {

0 commit comments

Comments
 (0)