Skip to content

Commit 31e1f8c

Browse files
yaacovCRIvanGoncharov
authored andcommitted
refactor handleFieldError
= integrate locatedError, which was always called on the input = avoid constant return value, which causes return value to hide value of this constant = add optional asyncPayloadRecord parameter so that caller does not have to supply errors list
1 parent a074400 commit 31e1f8c

File tree

1 file changed

+100
-49
lines changed

1 file changed

+100
-49
lines changed

src/execution/execute.ts

Lines changed: 100 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,6 @@ function executeField(
699699
path: Path,
700700
asyncPayloadRecord?: AsyncPayloadRecord,
701701
): PromiseOrValue<unknown> {
702-
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
703702
const fieldName = fieldGroup[0].name.value;
704703
const fieldDef = exeContext.schema.getField(parentType, fieldName);
705704
if (!fieldDef) {
@@ -761,18 +760,30 @@ function executeField(
761760
// Note: we don't rely on a `catch` method, but we do expect "thenable"
762761
// to take a second callback for the error case.
763762
return completed.then(undefined, (rawError) => {
764-
const error = locatedError(rawError, fieldGroup, pathToArray(path));
765-
const handledError = handleFieldError(error, returnType, errors);
763+
handleFieldError(
764+
rawError,
765+
exeContext,
766+
returnType,
767+
fieldGroup,
768+
path,
769+
asyncPayloadRecord,
770+
);
766771
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
767-
return handledError;
772+
return null;
768773
});
769774
}
770775
return completed;
771776
} catch (rawError) {
772-
const error = locatedError(rawError, fieldGroup, pathToArray(path));
773-
const handledError = handleFieldError(error, returnType, errors);
777+
handleFieldError(
778+
rawError,
779+
exeContext,
780+
returnType,
781+
fieldGroup,
782+
path,
783+
asyncPayloadRecord,
784+
);
774785
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
775-
return handledError;
786+
return null;
776787
}
777788
}
778789

@@ -804,20 +815,26 @@ export function buildResolveInfo(
804815
}
805816

806817
function handleFieldError(
807-
error: GraphQLError,
818+
rawError: unknown,
819+
exeContext: ExecutionContext,
808820
returnType: GraphQLOutputType,
809-
errors: Array<GraphQLError>,
810-
): null {
821+
fieldGroup: FieldGroup,
822+
path: Path,
823+
asyncPayloadRecord?: AsyncPayloadRecord | undefined,
824+
): void {
825+
const error = locatedError(rawError, fieldGroup, pathToArray(path));
826+
811827
// If the field type is non-nullable, then it is resolved without any
812828
// protection from errors, however it still properly locates the error.
813829
if (isNonNullType(returnType)) {
814830
throw error;
815831
}
816832

833+
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
834+
817835
// Otherwise, error protection is applied, logging the error and resolving
818836
// a null value for this field if one is encountered.
819837
errors.push(error);
820-
return null;
821838
}
822839

823840
/**
@@ -958,11 +975,16 @@ async function completePromisedValue(
958975
}
959976
return completed;
960977
} catch (rawError) {
961-
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
962-
const error = locatedError(rawError, fieldGroup, pathToArray(path));
963-
const handledError = handleFieldError(error, returnType, errors);
978+
handleFieldError(
979+
rawError,
980+
exeContext,
981+
returnType,
982+
fieldGroup,
983+
path,
984+
asyncPayloadRecord,
985+
);
964986
filterSubsequentPayloads(exeContext, path, asyncPayloadRecord);
965-
return handledError;
987+
return null;
966988
}
967989
}
968990

@@ -1036,7 +1058,6 @@ async function completeAsyncIteratorValue(
10361058
iterator: AsyncIterator<unknown>,
10371059
asyncPayloadRecord?: AsyncPayloadRecord,
10381060
): Promise<ReadonlyArray<unknown>> {
1039-
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
10401061
const stream = getStreamValues(exeContext, fieldGroup, path);
10411062
let containsPromise = false;
10421063
const completedResults: Array<unknown> = [];
@@ -1072,16 +1093,22 @@ async function completeAsyncIteratorValue(
10721093
break;
10731094
}
10741095
} catch (rawError) {
1075-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1076-
completedResults.push(handleFieldError(error, itemType, errors));
1096+
handleFieldError(
1097+
rawError,
1098+
exeContext,
1099+
itemType,
1100+
fieldGroup,
1101+
itemPath,
1102+
asyncPayloadRecord,
1103+
);
1104+
completedResults.push(null);
10771105
break;
10781106
}
10791107

10801108
if (
10811109
completeListItemValue(
10821110
iteration.value,
10831111
completedResults,
1084-
errors,
10851112
exeContext,
10861113
itemType,
10871114
fieldGroup,
@@ -1111,7 +1138,6 @@ function completeListValue(
11111138
asyncPayloadRecord?: AsyncPayloadRecord,
11121139
): PromiseOrValue<ReadonlyArray<unknown>> {
11131140
const itemType = returnType.ofType;
1114-
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
11151141

11161142
if (isAsyncIterable(result)) {
11171143
const iterator = result[Symbol.asyncIterator]();
@@ -1170,7 +1196,6 @@ function completeListValue(
11701196
completeListItemValue(
11711197
item,
11721198
completedResults,
1173-
errors,
11741199
exeContext,
11751200
itemType,
11761201
fieldGroup,
@@ -1196,7 +1221,6 @@ function completeListValue(
11961221
function completeListItemValue(
11971222
item: unknown,
11981223
completedResults: Array<unknown>,
1199-
errors: Array<GraphQLError>,
12001224
exeContext: ExecutionContext,
12011225
itemType: GraphQLOutputType,
12021226
fieldGroup: FieldGroup,
@@ -1236,14 +1260,16 @@ function completeListItemValue(
12361260
// to take a second callback for the error case.
12371261
completedResults.push(
12381262
completedItem.then(undefined, (rawError) => {
1239-
const error = locatedError(
1263+
handleFieldError(
12401264
rawError,
1265+
exeContext,
1266+
itemType,
12411267
fieldGroup,
1242-
pathToArray(itemPath),
1268+
itemPath,
1269+
asyncPayloadRecord,
12431270
);
1244-
const handledError = handleFieldError(error, itemType, errors);
12451271
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1246-
return handledError;
1272+
return null;
12471273
}),
12481274
);
12491275

@@ -1252,10 +1278,16 @@ function completeListItemValue(
12521278

12531279
completedResults.push(completedItem);
12541280
} catch (rawError) {
1255-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1256-
const handledError = handleFieldError(error, itemType, errors);
1281+
handleFieldError(
1282+
rawError,
1283+
exeContext,
1284+
itemType,
1285+
fieldGroup,
1286+
itemPath,
1287+
asyncPayloadRecord,
1288+
);
12571289
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1258-
completedResults.push(handledError);
1290+
completedResults.push(null);
12591291
}
12601292

12611293
return false;
@@ -1866,12 +1898,15 @@ function executeStreamField(
18661898
asyncPayloadRecord,
18671899
);
18681900
} catch (rawError) {
1869-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1870-
completedItem = handleFieldError(
1871-
error,
1901+
handleFieldError(
1902+
rawError,
1903+
exeContext,
18721904
itemType,
1873-
asyncPayloadRecord.errors,
1905+
fieldGroup,
1906+
itemPath,
1907+
asyncPayloadRecord,
18741908
);
1909+
completedItem = null;
18751910
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
18761911
}
18771912
} catch (error) {
@@ -1884,14 +1919,16 @@ function executeStreamField(
18841919
if (isPromise(completedItem)) {
18851920
const completedItems = completedItem
18861921
.then(undefined, (rawError) => {
1887-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1888-
const handledError = handleFieldError(
1889-
error,
1922+
handleFieldError(
1923+
rawError,
1924+
exeContext,
18901925
itemType,
1891-
asyncPayloadRecord.errors,
1926+
fieldGroup,
1927+
itemPath,
1928+
asyncPayloadRecord,
18921929
);
18931930
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1894-
return handledError;
1931+
return null;
18951932
})
18961933
.then(
18971934
(value) => [value],
@@ -1928,10 +1965,16 @@ async function executeStreamIteratorItem(
19281965
}
19291966
item = value;
19301967
} catch (rawError) {
1931-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1932-
const value = handleFieldError(error, itemType, asyncPayloadRecord.errors);
1968+
handleFieldError(
1969+
rawError,
1970+
exeContext,
1971+
itemType,
1972+
fieldGroup,
1973+
itemPath,
1974+
asyncPayloadRecord,
1975+
);
19331976
// don't continue if iterator throws
1934-
return { done: true, value };
1977+
return { done: true, value: null };
19351978
}
19361979
let completedItem;
19371980
try {
@@ -1947,22 +1990,30 @@ async function executeStreamIteratorItem(
19471990

19481991
if (isPromise(completedItem)) {
19491992
completedItem = completedItem.then(undefined, (rawError) => {
1950-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1951-
const handledError = handleFieldError(
1952-
error,
1993+
handleFieldError(
1994+
rawError,
1995+
exeContext,
19531996
itemType,
1954-
asyncPayloadRecord.errors,
1997+
fieldGroup,
1998+
itemPath,
1999+
asyncPayloadRecord,
19552000
);
19562001
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1957-
return handledError;
2002+
return null;
19582003
});
19592004
}
19602005
return { done: false, value: completedItem };
19612006
} catch (rawError) {
1962-
const error = locatedError(rawError, fieldGroup, pathToArray(itemPath));
1963-
const value = handleFieldError(error, itemType, asyncPayloadRecord.errors);
2007+
handleFieldError(
2008+
rawError,
2009+
exeContext,
2010+
itemType,
2011+
fieldGroup,
2012+
itemPath,
2013+
asyncPayloadRecord,
2014+
);
19642015
filterSubsequentPayloads(exeContext, itemPath, asyncPayloadRecord);
1965-
return { done: false, value };
2016+
return { done: false, value: null };
19662017
}
19672018
}
19682019

0 commit comments

Comments
 (0)