Skip to content

Commit

Permalink
Maintain original errors where possible (#637)
Browse files Browse the repository at this point in the history
* Maintain original errors where possible

* Updated changelog to include details of this change

* removed .only on new testErrors.ts
  • Loading branch information
stringbeans authored and freiksenet committed Mar 1, 2018
1 parent 8a9585d commit 69228d0
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### vNEXT

* When concatenating errors maintain a reference to the original for use downstream [Issue #480](https://github.com/apollographql/graphql-tools/issues/480) [PR #637](https://github.com/apollographql/graphql-tools/pull/637)


### v2.21.0

* Make iterall a runtime dependency [PR #627](https://github.com/apollographql/graphql-tools/pull/627)
Expand Down
10 changes: 9 additions & 1 deletion src/stitching/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ export function getErrorsFromParent(
};
}

class CombinedError extends Error {
public errors: Error[];
constructor(message: string, errors: Error[]) {
super(message);
this.errors = errors;
}
}

export function checkResultAndHandleErrors(
result: any,
info: GraphQLResolveInfo,
Expand All @@ -94,7 +102,7 @@ export function checkResultAndHandleErrors(
const newError =
result.errors.length === 1 && hasResult(result.errors[0])
? result.errors[0]
: new Error(concatErrors(result.errors));
: new CombinedError(concatErrors(result.errors), result.errors);

throw locatedError(
newError,
Expand Down
76 changes: 76 additions & 0 deletions src/test/testErrors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { assert } from 'chai';
import {
GraphQLResolveInfo
} from 'graphql';
import {
checkResultAndHandleErrors
} from '../stitching/errors';

import 'mocha';


class ErrorWithResult extends Error {
public result: any;
constructor(message: string, result: any) {
super(message);
this.result = result;
}
}

describe('Errors', () => {
describe('checkResultAndHandleErrors', () => {
it('persists single error with a result', done => {
const result = {
errors: [new ErrorWithResult('Test error', 'result')]
};
try {
checkResultAndHandleErrors(result, {} as GraphQLResolveInfo, 'responseKey');
} catch (e) {
assert.equal(e.message, 'Test error');
assert.isUndefined(e.originalError.errors);
done();
}
});

it('persists original errors without a result', done => {
const result = {
errors: [new Error('Test error')]
};
try {
checkResultAndHandleErrors(result, {} as GraphQLResolveInfo, 'responseKey');
} catch (e) {
assert.equal(e.message, 'Test error');
assert.isNotEmpty(e.originalError);
assert.isNotEmpty(e.originalError.errors);
assert.lengthOf(e.originalError.errors, result.errors.length);
result.errors.forEach((error, i) => {
assert.deepEqual(e.originalError.errors[i], error);
});

done();
}
});

it('combines errors and perists the original errors', done => {
const result = {
errors: [
new Error('Error1'),
new Error('Error2')
]
};
try {
checkResultAndHandleErrors(result, {} as GraphQLResolveInfo, 'responseKey');
} catch (e) {
assert.equal(e.message, 'Error1\nError2');
assert.isNotEmpty(e.originalError);
assert.isNotEmpty(e.originalError.errors);
assert.lengthOf(e.originalError.errors, result.errors.length);
result.errors.forEach((error, i) => {
assert.deepEqual(e.originalError.errors[i], error);
});

done();
}
});
});
});
1 change: 1 addition & 0 deletions src/test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ import './testMocking';
import './testResolution';
import './testMakeRemoteExecutableSchema';
import './testMergeSchemas';
import './testErrors';

0 comments on commit 69228d0

Please sign in to comment.