Custom errors raised by resolvers are not formatted
See original GitHub issueI’m attempting to mimic a couple of the errors in apollo-server, and want to include a code
value in the extensions, as such:
class AuthenticationError(Exception):
@property
def formatted(self) -> dict:
return {"message": self.message, "extensions": {"code": "UNAUTHENTICATED",}}
def throwError(_, info: ResolveInfo):
raise AuthenticationError("dummy auth error")
After much stack debugging, I discovered that python’s graphql.error.located_error.located_error()
is wrapping my custom child class in a new instance of GraphQLError
, so its formatted
property is never accessed by ariadne.
According to the ariadne error-messaging documentation, the default formatter “Unwraps GraphQL error by accessing its original_error property”. And while I realize that in the code this is happening exactly in the order described in the docs, this also means that the formatted = error.formatted
is being called on the result of located_error()
rather than the original one that was thrown.
Additionally, when I hook the debugger into format_error
, it shows that my original error is actually double-wrapped, and only accessible by drilling two layers deep via error.original_error.original_error
(the first level error.original_error
is another GraphQLError … not quite sure where the double-wrapping got added)
It feels like there is a bug in here somewhere (especially with that nested original_error), but it’s certainly the case where the documentation could use some work explaining what actually happens under the hood, since as written, it sounds like it should be possible to just add a formatted
property on an error and expect it to be reported to the API (which is definitely not the case).
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (8 by maintainers)
I’ve tried reproducing Apollo’s errors approach in past and I don’t remember it ever being nearly as troublesome as you are describing it, eg. I’ve never had to touch
formatter
logic in order to get those errors to work.So I’ve did a quick test and it turns out I was wrong: you aren’t supposed to extend
GraphQLError
in your exception, extending regularException
does the trick just fine:GraphQL response:
And same query with
DEBUG=False
:You also don’t need to write any custom formatting logic for this because when query executor wraps exception in
GraphQLError
, it doesgraphql_error.extensions = original_error.extensions
, effectively passing error code data up to error formatter.@nilansaha this is not related to this issue. Please ask question on discussions instead.