After experimenting with this for a bit, I realized that some important details are missing. Mainly, if you have a custom error object with custom fields, the above examples will allow you to read your custom properties because it appears that custom errors are casted into a standard Error
object with only a message property.
Here is what my formatError
function looks like (note the originalError
property):
app.use('/graphql', auth.verifyAccess, graphqlHTTP((req, res) => {
return {
schema: makeExecutableSchema({
typeDefs: typeDefs,
resolvers: rootResolver
}),
graphiql: true,
formatError: (err) => ({
message: err.originalError.message || err.message,
code: err.originalError.code || 500
}),
}
}));
The originalError
prop seems to always be set but as a safeguard you could use lodash get
property.
And I have a defined custom error class called APIError
class APIError extends Error {
constructor({ code, message }) {
const fullMsg = `${code}: ${message}`;
super(fullMsg);
this.code = code;
this.message = message;
}
}
export default APIError;
In my resolvers, I throw exceptions as such:
const e = new APIError({
code: 500,
message: 'Internal server error'
});