Skip to content

Commit

Permalink
subscribe: drop mapping of AsyncIterable errors
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Apr 4, 2021
1 parent 179e479 commit ee42a53
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 142 deletions.
62 changes: 0 additions & 62 deletions src/subscription/__tests__/mapAsyncIterator-test.js
Expand Up @@ -269,35 +269,6 @@ describe('mapAsyncIterator', () => {
.with.property('message', 'Goodbye');
});

it('maps over thrown errors if second callback provided', async () => {
async function* source() {
yield 'Hello';
throw new Error('Goodbye');
}

const doubles = mapAsyncIterator(
source(),
(x) => x + x,
(error) => error,
);

expect(await doubles.next()).to.deep.equal({
value: 'HelloHello',
done: false,
});

const result = await doubles.next();
expect(result.value)
.to.be.an.instanceOf(Error)
.with.property('message', 'Goodbye');
expect(result.done).to.equal(false);

expect(await doubles.next()).to.deep.equal({
value: undefined,
done: true,
});
});

async function testClosesSourceWithMapper<T>(mapper: (number) => T) {
let didVisitFinally = false;

Expand Down Expand Up @@ -353,37 +324,4 @@ describe('mapAsyncIterator', () => {
: Promise.resolve(x),
);
});

it('closes source if mapper throws an error', async () => {
async function* source() {
yield 1;
throw new Error(2);
}

const throwOver1 = mapAsyncIterator(
source(),
(x) => x,
(error) => {
throw new Error('Cannot count to ' + error.message);
},
);

expect(await throwOver1.next()).to.deep.equal({ value: 1, done: false });

let expectedError;
try {
await throwOver1.next();
} catch (error) {
expectedError = error;
}

expect(expectedError)
.to.be.an.instanceOf(Error)
.with.property('message', 'Cannot count to 2');

expect(await throwOver1.next()).to.deep.equal({
value: undefined,
done: true,
});
});
});
60 changes: 0 additions & 60 deletions src/subscription/__tests__/subscribe-test.js
Expand Up @@ -9,8 +9,6 @@ import { isAsyncIterable } from '../../jsutils/isAsyncIterable';
import type { DocumentNode } from '../../language/ast';
import { parse } from '../../language/parser';

import { GraphQLError } from '../../error/GraphQLError';

import { GraphQLSchema } from '../../type/schema';
import { GraphQLList, GraphQLObjectType } from '../../type/definition';
import { GraphQLInt, GraphQLString, GraphQLBoolean } from '../../type/scalars';
Expand Down Expand Up @@ -1031,62 +1029,4 @@ describe('Subscription Publish Phase', () => {
value: undefined,
});
});

it('should resolve GraphQL error from source event stream', async () => {
async function* generateEmails() {
yield { email: { subject: 'Hello' } };
throw new GraphQLError('test error');
}

const erroringEmailSchema = emailSchemaWithResolvers(
generateEmails,
(email) => email,
);

const subscription = await subscribe({
schema: erroringEmailSchema,
document: parse(`
subscription {
importantEmail {
email {
subject
}
}
}
`),
});
invariant(isAsyncIterable(subscription));

const payload1 = await subscription.next();
expect(payload1).to.deep.equal({
done: false,
value: {
data: {
importantEmail: {
email: {
subject: 'Hello',
},
},
},
},
});

const payload2 = await subscription.next();
expect(payload2).to.deep.equal({
done: false,
value: {
errors: [
{
message: 'test error',
},
],
},
});

const payload3 = await subscription.next();
expect(payload3).to.deep.equal({
done: true,
value: undefined,
});
});
});
17 changes: 3 additions & 14 deletions src/subscription/mapAsyncIterator.js
Expand Up @@ -7,9 +7,6 @@ import type { PromiseOrValue } from '../jsutils/PromiseOrValue';
export function mapAsyncIterator<T, U>(
iterable: AsyncIterable<T> | AsyncGenerator<T, void, void>,
callback: (T) => PromiseOrValue<U>,
rejectCallback: (any) => U = (error) => {
throw error;
},
): AsyncGenerator<U, void, void> {
// $FlowFixMe[prop-missing]
const iteratorMethod = iterable[Symbol.asyncIterator];
Expand Down Expand Up @@ -38,28 +35,20 @@ export function mapAsyncIterator<T, U>(
}
}

function mapReject(error: mixed) {
try {
return { value: rejectCallback(error), done: false };
} catch (callbackError) {
return abruptClose(callbackError);
}
}

/* TODO: Flow doesn't support symbols as keys:
https://github.com/facebook/flow/issues/3258 */
return ({
next(): Promise<IteratorResult<U, void>> {
return iterator.next().then(mapResult, mapReject);
return iterator.next().then(mapResult, abruptClose);
},
return() {
return typeof iterator.return === 'function'
? iterator.return().then(mapResult, mapReject)
? iterator.return().then(mapResult, abruptClose)
: Promise.resolve({ value: undefined, done: true });
},
throw(error?: mixed): Promise<IteratorResult<U, void>> {
if (typeof iterator.throw === 'function') {
return iterator.throw(error).then(mapResult, mapReject);
return iterator.throw(error).then(mapResult, abruptClose);
}
return Promise.reject(error).catch(abruptClose);
},
Expand Down
7 changes: 1 addition & 6 deletions src/subscription/subscribe.js
Expand Up @@ -104,12 +104,7 @@ export async function subscribe(
});

// Map every source value to a ExecutionResult value as described above.
return mapAsyncIterator(resultOrStream, mapSourceToResponse, (error) => {
if (error instanceof GraphQLError) {
return { errors: [error] };
}
throw error;
});
return mapAsyncIterator(resultOrStream, mapSourceToResponse);
}

/**
Expand Down

0 comments on commit ee42a53

Please sign in to comment.