diff --git a/graphene_django/filter/fields.py b/graphene_django/filter/fields.py index cb4254370..7dfd20a12 100644 --- a/graphene_django/filter/fields.py +++ b/graphene_django/filter/fields.py @@ -1,6 +1,7 @@ from collections import OrderedDict from functools import partial +from graphql.error import GraphQLError from graphene.types.argument import to_arguments from ..fields import DjangoConnectionField from .utils import get_filtering_args_from_filterset, get_filterset_class @@ -89,11 +90,22 @@ def connection_resolver( **args ): filter_kwargs = {k: v for k, v in args.items() if k in filtering_args} - qs = filterset_class( + + filterset = filterset_class( data=filter_kwargs, queryset=default_manager.get_queryset(), request=info.context, - ).qs + ) + + if not (filterset.is_bound and filterset.form.is_valid()): + exc = { + str(key): [str(e.message) for e in error_list] + for key, error_list in filterset.form.errors.as_data().items() + } + + raise GraphQLError(exc) + + qs = filterset.qs return super(DjangoFilterConnectionField, cls).connection_resolver( resolver, diff --git a/graphene_django/filter/tests/test_fields.py b/graphene_django/filter/tests/test_fields.py index f9ef0ae2f..18fdad65b 100644 --- a/graphene_django/filter/tests/test_fields.py +++ b/graphene_django/filter/tests/test_fields.py @@ -290,6 +290,37 @@ class Query(ObjectType): ) +def test_filter_filterset_validation_errors(): + class ReporterFilterNode(DjangoObjectType): + class Meta: + model = Reporter + interfaces = (Node,) + filter_fields = ("id",) + + class Query(ObjectType): + all_reporters = DjangoFilterConnectionField(ReporterFilterNode) + + r1 = Reporter.objects.create(first_name="r1", last_name="r1", email="r1@test.com") + + query = """ + query { + allReporters(id:"foo") { + edges { + node { + id + } + } + } + } + """ + schema = Schema(query=Query) + result = schema.execute(query) + + assert result.errors + # We should get back an error message + assert result.to_dict()['errors'][0]["message"] == "{'id': ['Invalid ID specified.']}" + + def test_global_id_field_implicit(): field = DjangoFilterConnectionField(ArticleNode, fields=["id"]) filterset_class = field.filterset_class