Claudio Medeiros
Claudio Medeiros

Reputation: 71

Graphene errors messages

I wonder if it is possible to translate the validation error messages that graphene provides? For example: "Authentication credentials were not provided" as shown in the code example below.

{
  "errors": [
    {
      "message": "Authentication credentials were not provided",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ],
  "data": {
    "viewer": null
  }
}

Upvotes: 7

Views: 5347

Answers (2)

ndpu
ndpu

Reputation: 22561

My Django form errors types, for example:

from graphene.utils.str_converters import to_camel_case


class DjangoFormError(graphene.ObjectType):
    field = graphene.String()
    message = graphene.String()

    @classmethod
    def list_from_errors_dict(cls: Type[T], django_form_errors: dict) -> List[T]:
        return [
            cls(field=to_camel_case(field), message=' '.join(messages))
            for field, messages in django_form_errors.items()
        ]


class DjangoFormErrorsByIdx(graphene.ObjectType):
    form_idx = graphene.Int()
    errors = graphene.List(DjangoFormError)

    @classmethod
    def list_from_idx_dict(cls: Type[T], errors_by_idx_dict: dict) -> List[T]:
        return [
            cls(
                form_idx=idx,
                errors=DjangoFormError.list_from_errors_dict(django_form_errors),
            )
            for idx, django_form_errors in errors_by_idx_dict.items()
        ]   

# ...
# in mutation
if not django_form.is_valid():
    form_errors = DjangoFormError.list_from_errors_dict(
        django_form.errors
    )

Upvotes: 0

user10645790
user10645790

Reputation: 1274

Create a custom error type

import graphene
from graphene_django.utils import camelize

class ErrorType(graphene.Scalar):
    @staticmethod
    def serialize(errors):
        if isinstance(errors, dict):
            if errors.get("__all__", False):
                errors["non_field_errors"] = errors.pop("__all__")
            return camelize(errors)
        raise Exception("`errors` should be dict!")

Add it to your mutations

class MyMutation(graphene.Mutation):

    # add the custom error type
    errors = graphene.Field(ErrorType)

    form = SomeForm

    @classmethod
    def mutate(cls, root, info, **kwargs):
        f = cls.form(kwargs)
        if f.is_valid():
            pass
        else:
            # pass the form error to your custom error type
            return cls(errors=f.errors.get_json_data())

Example

django-graphql-auth uses a similar error type, and it works like this, for example for registration:

mutation {
  register(
    email:"[email protected]",
    username:"skywalker",
    password1: "123456",
    password2:"123"
  ) {
    success,
    errors,
    token,
    refreshToken
  }
}

should return:

{
  "data": {
    "register": {
      "success": false,
      "errors": {
        "password2": [
          {
            "message": "The two password fields didn’t match.",
            "code": "password_mismatch"
          }
        ]
      },
      "token": null,
      "refreshToken": null
    }
  }
}

Upvotes: 4

Related Questions