Error handling
See original GitHub issueWe have decided to approach error handling like suggested in many blogs, by having errors defined as fields rather than raising exceptions.
The thing with this is that we need to make sure we catch every exception that we want to handle and somehow keep track of them to be able to inform them.
So we came up with:
class BaseObjectType(graphene.ObjectType):
class Meta:
abstract = True
@classmethod
def __init_subclass_with_meta__(
cls,
interfaces=(),
possible_types=(),
default_resolver=None,
_meta=None,
**options
):
super().__init_subclass_with_meta__(
interfaces, possible_types, default_resolver, _meta, **options)
for f in cls._meta.fields:
if f in ['errors']:
continue
resolver_name = "resolve_{}".format(f)
if hasattr(cls, resolver_name):
setattr(cls, resolver_name, catch_errors(getattr(cls, resolver_name)))
class BaseResponse(BaseObjectType):
class Meta:
abstract = True
errors = graphene.String()
@staticmethod
def resolve_errors(root, info, **kwargs):
operation_name = info.path[0]
error_key = f"{operation_name}_errors"
if not root.errors and error_key in info.context.errors:
root.errors = ",".join(info.context.errors[error_key])
return root.errors
catch_errors
just populates info.context.errors
for each operation
While implementing this approach for error handling I have also found an issue when resolving the error field. I have a base class that extends ObjectType by iterating over the resolvers and wrapping them to n catch any errors and setting an errors dict in the info.context.
Problem is that when resolving a type field that throws an exception, I do catch it and set the error, but the error field was already processed/resolved. Is there a way to force a particular field to be processed at the end or to force it to update? I need to make sure every resolver runs before the error field is resolver so I make sure all errors are caught.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:4
- Comments:31 (7 by maintainers)
Top GitHub Comments
Bump on this issue.
Error handling is a big deal when implementing any API and graphene’s middleware doesn’t offer any obvious way to do this.
A very common use case is catching all exceptions and stripping any internal error handling. This is crucial for security purposes: it’s not uncommon for stringified exceptions to have PII and other sensitive information.
The only way to do this in graphene is to decorate every resolver with error handling functionality or using the metaclass approach described above.
Ariadne, by contrast, treats this as a first class use case:
https://ariadnegraphql.org/docs/error-messaging
Is proper error handling somewhere on the roadmap?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.