Skip to content

Error handling #902

Closed
Closed
@sebastiandev

Description

@sebastiandev

We 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions