Express-graphql: The error formatter is dropping custom fields

Created on 26 Jun 2018  路  4Comments  路  Source: graphql/express-graphql

I am throwing an error in my handler but later in the formatError function the error object is of a different type and it has dropped all of my custom fields.

throw Object.assign(new Error('example'), { code: 'E_EXAMPLE' })
  app.use('/api', graphql({
    schema,
    rootValue: root
    graphiql: true,
    formatError: error => console.log(error) || ({
      message: error.message,
      code: error.code, // null, why?
      locations: error.locations,
      stack: error.stack ? error.stack.split('\n') : [],
      path: error.path
    })
  }))

How can I throw an error which has fields that persist into the error formatter?

Most helpful comment

@justinmchase Note that latest version of GraphQL spec changed things a bit:
https://github.com/facebook/graphql/releases/tag/June2018

Previously GraphQL did not make it clear how services should add additional data to errors. After #230, there was a concern that adding new features to errors could accidentally conflict with this additional data. Now, any additional data on an error should be contained within an extensions field.

In graphql-js v14.0.0(RC stage at the moment) extensions from original error would be formatted as error.extensions.code:
https://github.com/graphql/graphql-js/pull/1284

All 4 comments

@justinmchase It should be either:

throw Object.assign(new Error('example'), { extensions: {code: 'E_EXAMPLE' }})

Or you should use error.originalError.code inside formatError.

Perfect, both worked for me, thanks!

For the record in both cases extensions and originalError are propagated sub properties on the error. Such as:

throw Object.assign(new Error('example'), { A; 'a', extensions: { B: 'b' } })

// ...
formatError: ({ originalError: { A }, extensions: { B } }) => ({
  A,
  B
})

@justinmchase Note that latest version of GraphQL spec changed things a bit:
https://github.com/facebook/graphql/releases/tag/June2018

Previously GraphQL did not make it clear how services should add additional data to errors. After #230, there was a concern that adding new features to errors could accidentally conflict with this additional data. Now, any additional data on an error should be contained within an extensions field.

In graphql-js v14.0.0(RC stage at the moment) extensions from original error would be formatted as error.extensions.code:
https://github.com/graphql/graphql-js/pull/1284

originalError

Works for me. Here's how i did for those who are wondering. I created my own custom error:

'use strict'

module.exports = function CustomError(message, extra) {
  Error.captureStackTrace(this, this.constructor)
  this.name = this.constructor.name
  this.message = message
  this.extra = extra
}

require('util').inherits(module.exports, Error)

Threw the error in the resolver and then referenced my additional property like so:

app.use(
  '/graphql',
  graphqlHTTP(async (request, response, graphQLParams) => {
    return {
      schema,
      graphiql: process.env.NODE_ENV === 'development' ? true : false,
      context: {
        req: request
      },
      customFormatErrorFn: (error) => ({
        status: error.originalError.extra,
        message: error.message,
        locations: error.locations,
        stack: error.stack ? error.stack.split('\n') : [],
        path: error.path
      })
    }
  })
)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

violet-day picture violet-day  路  3Comments

phuchle2 picture phuchle2  路  3Comments

brunolemos picture brunolemos  路  5Comments

arunoda picture arunoda  路  4Comments

jamesmoriarty picture jamesmoriarty  路  4Comments