Hi,
I want to capture errors in the didEncounterErrors
hook and persist only some type of errors to my logging service while ignoring other types. What works well is when I import subclasses of the ApolloError
class from 'apollo-server-errors'
packages (BadUserInputError, ForbiddenError, etc) and throw that error in the resolver. I can then capture that error in didEncounterErrors
by doing something like:
plugins: [{
requestDidStart(ctx) {
return {
didEncounterErrors ({ errors }} {
for (const [_, error] of Object.entries(errors)) {
if (error.originalError instanceof BadUserInputError) {
continue; // ignore error
}
logger.writeError(error, ctx.context);
}
}
}
however, if the error is thrown by graphql itself, such as a mutation not matching the schema,
error.orginalError
is not available in didEncounterErrors
. I expect it to be available and it should be of type ValidationError
. It is, however, available in formatError
. I could handle error logging there, but I’ve read that best practice is to capture errors in didEncounterErrors
+ you do not have access to context
in formatError
.
Could anyone explain why when graphql throws a standard validation error, I don’t have access to the extensions property? Is there a way around this?
Pre-execution validation errors are indeed handled by graphql
(JS)'s validate
function which is invoked by Apollo Server in the request pipeline just after parsing the operation.
When a validation error is observed after invoking validate
(as determined by a non-zero length array being returned from validate
), we:
- Invoke any callback that was returned from the
validationDidStart
hook (that callback is known as “validation did end” and receives an array of GraphQLError
s.
- Invoke the
didEncounterErrors
life-cycle hook with the same array of errors.
The native graphql
(JS) error is not a ValidationError
, which is an Apollo-specific response treatment that currently happens after these life-cycle events.
I admit that it seems plausible to me that that treatment could happen earlier, but it does not today. It’s conceivable to me that if you wanted to pick them up in didEncounterErrors
that you could apply your own treatment to those errors in the “Validation did End” hook. There’s some documentation here if you wanted to take a look at how to setup that hook. It’s possible that you could, e.g., attach some additional properties to the error (or its extensions
) that you could use in the didEncounterErrors
hook. I might suggest something besides ValidationError
though, just in case we could eventually make that work natively.
In that spirit, if you’d like for this to happen natively in the future, I’d suggest opening a feature request.
Hope this helps!