Skip to content

Commit fe74c2e

Browse files
committed
EPR completeValueCatchingError
1 parent e2889ae commit fe74c2e

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

src/execution/execute.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -771,14 +771,27 @@ function resolveField(
771771
info,
772772
);
773773

774-
return completeValueCatchingError(
774+
const completed = completeValueCatchingError(
775775
exeContext,
776776
fieldDef.type,
777777
fieldNodes,
778778
info,
779779
path,
780780
result,
781781
);
782+
const promise = getPromise(completed);
783+
if (promise) {
784+
return promise.then(r => {
785+
if (r.errors && r.errors.length) {
786+
exeContext.errors.push.apply(exeContext.errors, r.errors);
787+
}
788+
return r.data;
789+
});
790+
}
791+
if (completed.errors && completed.errors.length) {
792+
exeContext.errors.push.apply(exeContext.errors, completed.errors);
793+
}
794+
return completed.data;
782795
}
783796

784797
export function buildResolveInfo(
@@ -852,23 +865,18 @@ function completeValueCatchingError(
852865
info: GraphQLResolveInfo,
853866
path: ResponsePath,
854867
result: mixed,
855-
): mixed {
868+
): ExecutionPartialResult<mixed> {
856869
// If the field type is non-nullable, then it is resolved without any
857870
// protection from errors, however it still properly locates the error.
858871
if (isNonNullType(returnType)) {
859-
const completed = completeValueWithLocatedError(
872+
return completeValueWithLocatedError(
860873
exeContext,
861874
returnType,
862875
fieldNodes,
863876
info,
864877
path,
865878
result,
866879
);
867-
const promise = getPromise(completed);
868-
if (promise) {
869-
return promise.then(r => r.data);
870-
}
871-
return completed.data;
872880
}
873881

874882
// Otherwise, error protection is applied, logging the error and resolving
@@ -888,17 +896,16 @@ function completeValueCatchingError(
888896
// the rejection error and resolve to null.
889897
// Note: we don't rely on a `catch` method, but we do expect "thenable"
890898
// to take a second callback for the error case.
891-
return promise.then(r => r.data).then(undefined, error => {
892-
exeContext.errors.push(error);
893-
return null;
894-
});
899+
return promise.then(undefined, error => ({
900+
data: null,
901+
errors: [error],
902+
}));
895903
}
896-
return completed.data;
904+
return completed;
897905
} catch (error) {
898906
// If `completeValueWithLocatedError` returned abruptly (threw an error),
899907
// log the error and return null.
900-
exeContext.errors.push(error);
901-
return null;
908+
return { data: null, errors: [error] };
902909
}
903910
}
904911

@@ -1107,8 +1114,22 @@ function completeListValue(
11071114
});
11081115

11091116
return containsPromise
1110-
? Promise.all(completedResults).then(data => ({ data }))
1111-
: { data: completedResults };
1117+
? Promise.all(completedResults).then(r => flattenEPRs(r))
1118+
: flattenEPRs(completedResults);
1119+
}
1120+
1121+
function flattenEPRs(
1122+
eprs: $ReadOnlyArray<ExecutionPartialResult<mixed>>,
1123+
): ExecutionPartialResult<mixed> {
1124+
const errors = [];
1125+
const data = [];
1126+
forEach((eprs: any), item => {
1127+
data.push(item.data);
1128+
if (item.errors && item.errors.length) {
1129+
errors.push.apply(errors, item.errors);
1130+
}
1131+
});
1132+
return { data, errors };
11121133
}
11131134

11141135
/**

0 commit comments

Comments
 (0)