Skip to content

Commit

Permalink
Fix @apollo/client/link/schema to return errors for invalid queries (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
amannn authored Oct 1, 2020
1 parent 7d002b2 commit 78198f8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 26 deletions.
59 changes: 41 additions & 18 deletions src/link/schema/__tests__/schemaLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ type Query {
const schema = makeExecutableSchema({ typeDefs });

describe('SchemaLink', () => {
const mockError = { throws: new TypeError('mock me') };

it('raises warning if called with concat', () => {
const link = new SchemaLink({ schema });
const _warn = console.warn;
Expand Down Expand Up @@ -56,7 +54,9 @@ describe('SchemaLink', () => {
});
observable.subscribe({
next,
error: error => expect(false),
error: () => {
throw new Error('Received error')
},
complete: () => {
expect(next).toHaveBeenCalledTimes(1);
done();
Expand All @@ -65,23 +65,26 @@ describe('SchemaLink', () => {
});

it('calls error when fetch fails', done => {
const badSchema = makeExecutableSchema({ typeDefs });

const link = new SchemaLink({ schema: badSchema });
const schema = makeExecutableSchema({
typeDefs,
resolvers: {
Query: {
sampleQuery() {
throw new Error('Unauthorized');
}
}
}
});
const link = new SchemaLink({ schema });
const observable = execute(link, {
query: sampleQuery,
});
observable.subscribe(
result => expect(false),
error => {
expect(error).toEqual(mockError.throws);
done();
},
() => {
expect(false);
done();
},
);
observable.subscribe(result => {
expect(result.errors).toBeTruthy()
expect(result.errors!.length).toBe(1)
expect(result.errors![0].message).toMatch(/Unauthorized/)
done();
});
});

it('supports query which is executed synchronously', done => {
Expand All @@ -101,7 +104,9 @@ describe('SchemaLink', () => {
});
observable.subscribe(
next,
error => expect(false),
() => {
throw new Error('Received error')
},
() => {
expect(next).toHaveBeenCalledTimes(1);
done();
Expand Down Expand Up @@ -192,4 +197,22 @@ describe('SchemaLink', () => {
},
);
});

it('reports errors for unknown queries', done => {
const schema = makeExecutableSchema({typeDefs})
const link = new SchemaLink({ schema });
const observable = execute(link, {
query: gql`
query {
unknown
}
`
});
observable.subscribe(result => {
expect(result.errors).toBeTruthy()
expect(result.errors!.length).toBe(1)
expect(result.errors![0].message).toMatch(/Cannot query field "unknown"/)
done();
});
});
});
24 changes: 16 additions & 8 deletions src/link/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { execute } from 'graphql/execution/execute';
import { validate } from 'graphql/validation/validate';
import { GraphQLSchema } from 'graphql/type/schema';

import { ApolloLink, Operation, FetchResult } from '../core';
Expand Down Expand Up @@ -48,14 +49,21 @@ export class SchemaLink extends ApolloLink {
? this.context(operation)
: this.context
)
).then(context => execute(
this.schema,
operation.query,
this.rootValue,
context,
operation.variables,
operation.operationName,
)).then(data => {
).then(context => {
const validationErrors = validate(this.schema, operation.query);
if (validationErrors.length > 0) {
return { errors: validationErrors };
}

return execute(
this.schema,
operation.query,
this.rootValue,
context,
operation.variables,
operation.operationName,
)
}).then(data => {
if (!observer.closed) {
observer.next(data);
observer.complete();
Expand Down

0 comments on commit 78198f8

Please sign in to comment.