Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transformSchema handles errors incorrectly #1367

Closed
tomkoufakis opened this issue Apr 15, 2020 · 5 comments · Fixed by #1371
Closed

transformSchema handles errors incorrectly #1367

tomkoufakis opened this issue Apr 15, 2020 · 5 comments · Fixed by #1371

Comments

@tomkoufakis
Copy link

PROBLEM DESCRIPTION:

If I throw a custom exception from inside a resolver using:

const createError = require('apollo-errors').createError; createError('SearchAPIError', { data: { code: '5xx' }, message: 'SearchAPI Error', { showPath: true, showLocations: true } })

The transformSchema call:
publicExecutableSchema = transformSchema(publicExecutableSchema, [ new FilterAndTransformSchema(publicSchemaConfig, config.public.strict) ]);

Normally without calling transformSchema, the errors returned from the GQL API might look like:

{ "errors": [ { "message": "SearchAPI Error", "locations": [ { "line": 2, "column": 3 } ], "path": [ "home_search" ], "name": "SearchAPIError", "time_thrown": "2020-04-15T17:12:35.189Z", "data": { "code": "5xx", "error": "ValidationMessage", "message": "\"limit\" must be less than or equal to 200", "description": "A validation error occurred" } } ] ....

However when I use transformSchema I find that name, time_thrown, and data fields are stripped out of the error object. The stack trace also follows a different path when transformSchema is in the mix. With transformSchema I lose the stack trace of the actual error and instead get a path related to "new CombinedError (....". The exception type thrown is GraphQLError instead of SearchAPIError.

Cases:

  • No call to transformSchema: everything works fine
  • Call to transformSchema but no transformations specified: the bug occurs
  • Call to transformSchema with transformations specified: the bug occurs

INTENDED OUTCOME:

  1. The stack trace shows the actual stack trace of the error
  2. The results returned include the data from the custom error indicated above

ACTUAL OUTCOME:

  1. The stack trace does not contain useful information because the exception is wrapped
  2. The results returned does not contain the validation message encapsulated in the thrown error

HOW TO REPRODUCE THE ISSUE:

  1. Using express-graphql, host a graphql endpoint who's executable schema is passed through transformSchema
  2. Throw an error in a resolver createError indicated above
@tomkoufakis
Copy link
Author

Additional info:

It seems that when we are logging the error, we also call:

require('apollo-errors').formatError(error);

This should unwrap the originalError parameter. However somewhere along the way in the Apollo/GraphQL code, the ApolloError type is lost and the originalError is of type Object. As a result the fields needed are missing.

@tomkoufakis
Copy link
Author

As a workaround what I did was:

  1. construct the GraphQL options with formatError:

{ schema: schema, formatError: logger.getErrorFormatter(request.context, graphQLParams), ... }

  1. In the getErrorFormatter function above I unwrapped the wrapped error:

let thrownError = error; if (path(["originalError", "errors", "0"], error)) { thrownError = path(["originalError", "errors", "0"], error); }

Now I am working with the correct error: thrownError.

Note: the contract to formatError shouldn't change depending if I use transformSchema or not. If I throw an error, formatError should expect to get that error that I had thrown.

yaacovCR added a commit that referenced this issue Apr 17, 2020
 = combineErrors now returns the originalError if one is present.
 = relocating an error is not necessary prior to throwing, and may cause the original error to be lost.
 = The CombinedError class now inherits from GraphQLError rather than directly from error to utilize its methods of properly allow extending the base Error class.

 Hopefully fixes #1367.
yaacovCR added a commit that referenced this issue Apr 17, 2020
 = combineErrors now returns the originalError if one is present.
 = relocating an error is not necessary prior to throwing, and may cause the original error to be lost.
 = The CombinedError class now inherits from GraphQLError rather than directly from error to utilize its methods of properly allow extending the base Error class.

 Hopefully fixes #1367.
@yaacovCR yaacovCR reopened this Apr 17, 2020
@yaacovCR yaacovCR added the waiting-for-release Fixed/resolved, and waiting for the next stable release label Apr 17, 2020
@yaacovCR
Copy link
Collaborator

yaacovCR commented Apr 17, 2020

@tomkoufakis not 100% sure this will fix your issue but I think it heads in the right direction and may actually work.

Just curious whether this was working in v4.

@yaacovCR
Copy link
Collaborator

Hopefully fixed with latest alpha, npm install graphql-tools@alpha.

@yaacovCR
Copy link
Collaborator

Closed by #1419.

@yaacovCR yaacovCR removed the waiting-for-release Fixed/resolved, and waiting for the next stable release label May 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants