From b24cbcde325d6e53788debae9818dd8cddebf9e1 Mon Sep 17 00:00:00 2001 From: Jimmy Jia Date: Mon, 13 Aug 2018 12:52:56 -0400 Subject: [PATCH] Make error handling consistent in createSourceEventStream --- src/subscription/subscribe.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/subscription/subscribe.js b/src/subscription/subscribe.js index ebd52f8086..5f9ad16709 100644 --- a/src/subscription/subscribe.js +++ b/src/subscription/subscribe.js @@ -35,8 +35,9 @@ import { getOperationRootType } from '../utilities/getOperationRootType'; * Implements the "Subscribe" algorithm described in the GraphQL specification. * * Returns a Promise which resolves to either an AsyncIterator (if successful) - * or an ExecutionResult (client error). The promise will be rejected if a - * server error occurs. + * or an ExecutionResult (error). The promise will be rejected if the schema or + * other arguments to this function are invalid, or if the resolved event stream + * is not an async iterable. * * If the client-provided arguments to this function do not result in a * compliant subscription, a GraphQL Response (ExecutionResult) with @@ -171,7 +172,6 @@ function subscribeImpl( reportGraphQLError, ) : ((resultOrStream: any): ExecutionResult), - reportGraphQLError, ); } @@ -179,11 +179,21 @@ function subscribeImpl( * Implements the "CreateSourceEventStream" algorithm described in the * GraphQL specification, resolving the subscription source event stream. * - * Returns a Promise. + * Returns a Promise which resolves to either an AsyncIterable (if successful) + * or an ExecutionResult (error). The promise will be rejected if the schema or + * other arguments to this function are invalid, or if the resolved event stream + * is not an async iterable. * - * If the client-provided invalid arguments, the source stream could not be - * created, or the resolver did not return an AsyncIterable, this function will - * will throw an error, which should be caught and handled by the caller. + * If the client-provided arguments to this function do not result in a + * compliant subscription, a GraphQL Response (ExecutionResult) with + * descriptive errors and no data will be returned. + * + * If the the source stream could not be created due to faulty subscription + * resolver logic or underlying systems, the promise will resolve to a single + * ExecutionResult containing `errors` and no `data`. + * + * If the operation succeeded, the promise resolves to the AsyncIterable for the + * event stream returned by the resolver. * * A Source Event Stream represents a sequence of events, each of which triggers * a GraphQL execution for that event. @@ -270,7 +280,11 @@ export function createSourceEventStream( return Promise.resolve(result).then(eventStream => { // If eventStream is an Error, rethrow a located error. if (eventStream instanceof Error) { - throw locatedError(eventStream, fieldNodes, responsePathAsArray(path)); + return { + errors: [ + locatedError(eventStream, fieldNodes, responsePathAsArray(path)), + ], + }; } // Assert field returned an event stream, otherwise yield an error. @@ -284,6 +298,8 @@ export function createSourceEventStream( ); }); } catch (error) { - return Promise.reject(error); + return error instanceof GraphQLError + ? Promise.resolve({ errors: [error] }) + : Promise.reject(error); } }