Nest: Cannot catch GraphQL Errors

Created on 11 Apr 2018  路  7Comments  路  Source: nestjs/nest

I'm submitting a...

[x] Bug report
[x] Documentation issue or request

Current behavior

Using the example provided in the documentation, when defining a module that uses the graphqlExpress middleware and using graphql-custom-types I can't catch any kind of errors of the type GraphQLError. This means that cannot enforce or improve errors in this scenario.

Expected behavior

I can catch errors by type

Minimal reproduction of the problem with instructions

Following the GraphQL example and adding graphql-custom-types packages. When for example instantiating UUID in a query, this dispatcher never reaches the code.

import { GraphQLError } from 'graphql/error';

@Catch(GraphQLError)
export class DispatchError implements ExceptionFilter {
  public catch(err, res) {
    console.log('NEVER REACHES THIS POINT')
  }
}

What is the motivation / use case for changing the behavior?

Improve errors response depending Server needs.

Environment


Nest version: 4.6.6

For Tooling issues:
- Node version:  9.5.0
- Platform:  Mac
type

All 7 comments

I will love help debugging this. So far I could reduce the error in the ApolloServer layer. It seems the express handler is not triggering errors properly. It handles exceptions inside the handler and forces everything to return a response instead of bypassing the error https://github.com/apollographql/apollo-server/blob/master/packages/apollo-server-express/src/expressApollo.ts#L54

Since this is in the Apollo Server layer, probably a bug there should be reported, but in the meantime, a workaround could be interesting using Nest. Not sure how to modify headers when a res.end() was executed.

Since the official documentation example uses graphqlExpress from Apollo Server I didn't find any other approach than reporting the bug in Apollo Server since this is super opinionated I planned 2 different approaches to solve the issue.

1) The hard/hotfix way: I created a function middleware to wrap graphqlExpress, and forced formatError option to notify of an error using next, and then will catch this error using any mean, inside/outside nest. This will trigger the error of unhandled promise since headers are already sent by expressApollo, awful hot-fix.

// application.module.ts
consumer
  .apply(
    (req, res, next) => {
      graphqlExpress((req, res) => {
        return {
          schema,
          rootValue: req,
          formatError: (err) => {
            next(err)
          }
        }
      })(req, res, next)
    }
  )
  .forRoutes({ path: '/', method: RequestMethod.ALL })

...
// main.ts
process.on('unhandledRejection', (err) => {
  if (process.env.NODE_ENV === 'development') {
    console.log('Caught exception: ' + err);
  }
});

2) The Nest way: I will create a specific Middleware for Apollo instead of using expressApollo, will be more like to nestApollo, since the ExceptionFilter and Interceptors are not working at all right now with this middleware. The example shows the fast solution, but not the most flexible on how Nest do things.

Hey @fjcero,
Apollo GraphQL middleware runs outside from exceptions filters context. As you already figured out, a workaround is to use formatError but it still has a huge downside (it helps only with the logging part). We definitely have to create our own middleware, dedicated for Nest users. However, I'd recommend to move this issue into @nestjs/graphql repository.

@kamilmysliwiec Agree, I will move the issue to @nestjs/graphql and will create a Pull Request with this change 馃檪

@fjcero ,I still have this problem

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings