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?
@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
})
}
})
)
Most helpful comment
@justinmchase Note that latest version of GraphQL spec changed things a bit:
https://github.com/facebook/graphql/releases/tag/June2018
In
graphql-jsv14.0.0(RC stage at the moment)extensionsfrom original error would be formatted aserror.extensions.code:https://github.com/graphql/graphql-js/pull/1284