Skip to content

Commit

Permalink
Merge pull request #173 from apollostack/empty-error-array
Browse files Browse the repository at this point in the history
Fix #156 by accepting non-spec-compliant empty error array
  • Loading branch information
Sashko Stubailo committed May 4, 2016
2 parents 1a15e68 + fd35788 commit eaeabe2
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Expect active development and potentially significant breaking changes in the `0.x` track. We'll try to be diligent about releasing a `1.0` version in a timely fashion (ideally within 1 or 2 months), so that we can take advantage of SemVer to signify breaking changes from that point on.

### vNEXT

- Made client more robust in the case where the server returns an empty error array, even though that's not in the GraphQL spec. [Issue #156](https://github.com/apollostack/apollo-client/issues/155) [PR #173](https://github.com/apollostack/apollo-client/pull/173)

### v0.3.0

- **Breaking change:** Require all queries to be wrapped with a `gql` template literal tag, and throw an error when they aren't. [Issue #155](https://github.com/apollostack/apollo-client/issues/155) [PR #168](https://github.com/apollostack/apollo-client/pull/168)
Expand Down
7 changes: 7 additions & 0 deletions src/data/resultUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {
GraphQLResult,
} from 'graphql';

export function graphQLResultHasError(result: GraphQLResult) {
return result.errors && result.errors.length;
}
6 changes: 5 additions & 1 deletion src/data/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import {
ApolloReducerConfig,
} from '../store';

import {
graphQLResultHasError,
} from './resultUtils';

export interface NormalizedCache {
[dataId: string]: StoreObject;
}
Expand Down Expand Up @@ -53,7 +57,7 @@ export function data(
}

// XXX handle partial result due to errors
if (!action.result.errors) {
if (! graphQLResultHasError(action.result)) {
const queryStoreValue = queries[action.queryId];

// XXX use immutablejs instead of cloning
Expand Down
6 changes: 5 additions & 1 deletion src/queries/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import {
isQueryStopAction,
} from '../actions';

import {
graphQLResultHasError,
} from '../data/resultUtils';

import {
SelectionSet,
GraphQLError,
Expand Down Expand Up @@ -74,7 +78,7 @@ export function queries(
}

const newState = assign({}, previousState) as QueryStore;
const resultHasGraphQLErrors = action.result.errors && action.result.errors.length;
const resultHasGraphQLErrors = graphQLResultHasError(action.result);

newState[action.queryId] = assign({}, previousState[action.queryId], {
loading: false,
Expand Down
96 changes: 96 additions & 0 deletions test/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,102 @@ describe('QueryManager', () => {
});
});

it('handles GraphQL errors with data returned', (done) => {
const query = gql`
query people {
allPeople(first: 1) {
people {
name
}
}
}
`;

const networkInterface = mockNetworkInterface(
{
request: {query },
result: {
data: {
allPeople: {
people: {
name: 'Ada Lovelace',
},
},
},
errors: [
{
name: 'Name',
message: 'This is an error message.',
},
],
},
}
);

const queryManager = new QueryManager({
networkInterface,
store: createApolloStore(),
reduxRootKey: 'apollo',
});

const handle = queryManager.watchQuery({
query,
});

handle.subscribe({
next(result) {
assert.equal(result.errors[0].message, 'This is an error message.');
done();
},
});
});

it('empty error array (handle non-spec-compliant server) #156', (done) => {
const query = gql`
query people {
allPeople(first: 1) {
people {
name
}
}
}
`;

const networkInterface = mockNetworkInterface(
{
request: {query },
result: {
data: {
allPeople: {
people: {
name: 'Ada Lovelace',
},
},
},
errors: [],
},
}
);

const queryManager = new QueryManager({
networkInterface,
store: createApolloStore(),
reduxRootKey: 'apollo',
});

const handle = queryManager.watchQuery({
query,
});

handle.subscribe({
next(result) {
assert.equal(result.data['allPeople'].people.name, 'Ada Lovelace');
assert.notProperty(result, 'errors');
done();
},
});
});

it('handles network errors', (done) => {
const query = gql`
query people {
Expand Down

0 comments on commit eaeabe2

Please sign in to comment.