Skip to content

Commit ea1894a

Browse files
authored
change incorrect subscribe return type to a GraphQLError rather than a systems error (#3621)
...in parallel to field-level resolver errors within the non-subscription execution algorithm. Note the addition of the path, an at-least rough correspondence to field execution initiation.
1 parent 2deb272 commit ea1894a

File tree

2 files changed

+21
-18
lines changed

2 files changed

+21
-18
lines changed

src/execution/__tests__/subscribe-test.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,16 @@ describe('Subscription Initialization Phase', () => {
454454
});
455455

456456
it('throws an error if subscribe does not return an iterator', async () => {
457-
(await expectPromise(subscribeWithBadFn(() => 'test'))).toRejectWith(
458-
'Subscription field must return Async Iterable. Received: "test".',
459-
);
457+
expectJSON(await subscribeWithBadFn(() => 'test')).toDeepEqual({
458+
errors: [
459+
{
460+
message:
461+
'Subscription field must return Async Iterable. Received: "test".',
462+
locations: [{ line: 1, column: 16 }],
463+
path: ['foo'],
464+
},
465+
],
466+
});
460467
});
461468

462469
it('resolves to an error for subscription resolver errors', async () => {

src/execution/subscribe.ts

+11-15
Original file line numberDiff line numberDiff line change
@@ -157,28 +157,15 @@ export async function createSourceEventStream(
157157
try {
158158
const eventStream = await executeSubscription(exeContext);
159159

160-
// Assert field returned an event stream, otherwise yield an error.
161-
if (!isAsyncIterable(eventStream)) {
162-
throw new Error(
163-
'Subscription field must return Async Iterable. ' +
164-
`Received: ${inspect(eventStream)}.`,
165-
);
166-
}
167-
168160
return eventStream;
169161
} catch (error) {
170-
// If it GraphQLError, report it as an ExecutionResult, containing only errors and no data.
171-
// Otherwise treat the error as a system-class error and re-throw it.
172-
if (error instanceof GraphQLError) {
173-
return { errors: [error] };
174-
}
175-
throw error;
162+
return { errors: [error] };
176163
}
177164
}
178165

179166
async function executeSubscription(
180167
exeContext: ExecutionContext,
181-
): Promise<unknown> {
168+
): Promise<AsyncIterable<unknown>> {
182169
const { schema, fragments, operation, variableValues, rootValue } =
183170
exeContext;
184171

@@ -238,6 +225,15 @@ async function executeSubscription(
238225
if (eventStream instanceof Error) {
239226
throw eventStream;
240227
}
228+
229+
// Assert field returned an event stream, otherwise yield an error.
230+
if (!isAsyncIterable(eventStream)) {
231+
throw new GraphQLError(
232+
'Subscription field must return Async Iterable. ' +
233+
`Received: ${inspect(eventStream)}.`,
234+
);
235+
}
236+
241237
return eventStream;
242238
} catch (error) {
243239
throw locatedError(error, fieldNodes, pathToArray(path));

0 commit comments

Comments
 (0)