7

I am trying to do customize messaging with GraphQLError.

There are few use cases that I want to handle with GraphQL Error:

  • when username and password did not match, I want to return customize the message that username and password did not match.

  • When the user entered an invalid email, I want to return customize the message that entered email is not valid.

  • And few other use cases.

I created a ValidateError.js File to use GraphQLError handling function:

const { GraphQLError } = require('graphql');

module.exports  = class ValidationError extends GraphQLError {
  constructor(errors) {

    super('The request is invalid');

    var err = errors.reduce((result, error) => {

        if (Object.prototype.hasOwnProperty.call(result, error.key)) {
          result[error.key].push(error.message);
        } else {
          result[error.key] = [error.message];
        }

        return result;
      }, {});
  }
}

Here is the code of my application index file app.js:

app.use('/graphql', graphqlExpress(req => ({
  schema,
  context: {
    user: req.user
  },
  formatError(err) {
    return {
      message: err.message,
      code: err.originalError && err.originalError.code,   
      locations: err.locations,
      path: err.path
    };
  }
})));

My question is how can I use this function for grabbing graphQLError

formatError

Thanks in advance.

Lin Du
  • 88,126
  • 95
  • 281
  • 483
Piyush Bansal
  • 1,635
  • 4
  • 16
  • 39

2 Answers2

6

"apollo-server-express": "^1.3.5"

"graphql": "^0.13.2"

Just throw your error in resolver, formatError function will catch each error thrown in resolver.

Here is my work:

appError.js

class AppError extends Error {
  constructor(opts) {
    super(opts.msg);
    this.code = opts.code;
  }
}

exports.AppError = AppError;

throw an custom error in resolver:

throw new AppError({ msg: 'authorization failed', code: 1001 });

catch this error in formatError:

  formatError: error => {
    const { code, message } = error.originalError;
    return { code, message };
  },

Other sample:

throw your error in resolver:

const resolvers = {
  Query: {
    books: () => {
      throw new GraphQLError('something bad happened');
    }
  }
};

catch error in formatError:

graphqlExpress(req => {
    return {
      schema,
      formatError: err => {
        console.log('format error');
        return err;
      }
    };
  })

Here is the output:

format error
GraphQLError: something bad happened
    at books (/Users/ldu020/workspace/apollo-server-express-starter/src/graphql-error/index.js:23:13)
    at /Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql-tools/dist/schemaGenerator.js:518:26
    at resolveFieldValueOrError (/Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:531:18)
    at resolveField (/Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:495:16)
    at /Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:364:18
    at Array.reduce (<anonymous>)
    at executeFields (/Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:361:42)
    at executeOperation (/Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:289:122)
    at executeImpl (/Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:154:14)
    at Object.execute (/Users/ldu020/workspace/apollo-server-express-starter/node_modules/graphql/execution/execute.js:131:229)
Lin Du
  • 88,126
  • 95
  • 281
  • 483
1

Inside of GraphQLError you should have access to GraphQLErrorExtensions which should allow you to append your custom messages when throwing errors.

This answer was written with knowledge of apollo server throwing custom errors through this extensions option. This may be achievable but more complex. I suggest checking out apollo server error: https://github.com/apollographql/apollo-server/blob/main/packages/apollo-server-errors/src/index.ts


It looks like what you can do is just pass any additional information through the extensions, but you will only be able to set it inside the constructor: new GraphQLError('your error message', null, null, null, null, null, {"message1": [ "custom message1" ], "message2": [ "customer message1", "custom message2" ]})

Nodiril
  • 21
  • 3