Skip to content

raise GraphQLError inside resolver gives me "Received incompatible instance error" after bumping from 3.0.0b7 to 3.0.0b8 #1367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
zhoudaxia233 opened this issue Nov 9, 2022 · 6 comments
Labels

Comments

@zhoudaxia233
Copy link

zhoudaxia233 commented Nov 9, 2022

  • What is the current behavior?
  • In graphene-django 3.0.0b8
class Query(ObjectType):
    me = graphene.Field(UserNode)
    def resolve_me(root, info):
        if user.is_anonymous or not user.is_active:
            raise GraphQLError("Unauthenticated.")
        return user

If I send the query without logging in, I get
"Received incompatible instance "<Promise at 0x7ff118d710b1 rejected with GraphQLError('Unauthenticated.')>"."

However, in 3.0.0b7, if I send the same query without logging in, I get
"Unauthenticated." (And this is the behavior I expected.)

  • Please tell us about your environment:

    • Version: graphene-django==3.0.0b8 graphql-core==3.1.7 graphql-relay==3.1.1
    • Platform: Ubuntu
@zhoudaxia233
Copy link
Author

https://github.com/graphql-python/graphene-django/blob/v3.0.0b8/graphene_django/debug/middleware.py#L69

https://github.com/graphql-python/graphene-django/blob/v3.0.0b7/graphene_django/debug/middleware.py

promise = next(root, info, **args)

has been changed to

try:
    promise = next(root, info, **args)
except Exception as e:
    return context.django_debug.on_resolve_error(e)

I guess this is the reason, but I have no idea how I could achieve the same result with the new version of graphene-django.

@pixel8r
Copy link

pixel8r commented Nov 13, 2022

I'm having the same issue in 3.0.0 (clean install with pip install graphene-django)

  • graphene 3.1.1
  • graphene-django 3.0.0
  • graphql-core 3.2.3
  • graphql-relay 3.2.0

test case:

class Query(graphene.ObjectType):
    hello_world = graphene.String()

    def resolve_hello_world(root, info):
        raise GraphQLError("hello error")
        return "hello"

schema = graphene.Schema(query=Query)

query:

{
    helloWorld
}

result (unexpected behavior):

{
  "data": {
    "helloWorld": "<Promise at 0x109c77550 rejected with GraphQLError('hello error')>"
  }
}

result (expected behavior) using same code and query with previous release:

  • graphene 2.1.9
  • graphene-django 2.15.0
  • graphql-core 2.3.2
  • graphql-relay 2.0.1
{
  "errors": [
    {
      "message": "hello error",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "helloWorld"
      ]
    }
  ],
  "data": {
    "helloWorld": null
  }
}

@zhoudaxia233
Copy link
Author

zhoudaxia233 commented Nov 13, 2022

@dobsonjon Hi, I found a workaround and maybe this is helpful for you. This issue is caused by their update on the default DjangoDebugMiddleware, however, this is customizable. Here
I just copy the old code and create a MyDjangoDebugMiddleware file, then replace the default one with my customized implementation (actually it's their old version implementation) by specifying the path in the GRAPHENE settings.

GRAPHENE = {
    ...
    'MIDDLEWARE': [
        'myproject.middlewares.MyDjangoDebugMiddleware',
    ]
}

Hope this helps.

@pixel8r
Copy link

pixel8r commented Nov 15, 2022

Thanks @zhoudaxia233

Would that affect me even if I'm not using graphene's debug middleware? I have not enabled that feature explicitly anyway. My graphene settings just look like this:

GRAPHENE = {
    "SCHEMA": "helloworld.schema.schema"
}

I do see a difference in this behavior when running on Django's built-in server vs a web server though. When running in my staging environment - (Django + GUnicorn + Caddy2), the errors section of the response appears as expected.

When running locally using Django's development server with DEBUG=False, the errors are also formatted correctly. However, when encountering multiple errors, I only get the first one.

When running locally using Django's development server with DEBUG=True, I get the "<Promise at 0x109c77550 rejected with GraphQLError('hello error')>" response I quoted above.

So it's not unusable, but this difference in behavior makes it very difficult to test effectively.

I'm using Django 3.2.16 if that matters.

@pixel8r
Copy link

pixel8r commented Nov 15, 2022

Ok @zhoudaxia233 I followed your suggestion and defined a custom DjangoDebugMiddleware class with the following change to the original class found in graphene_django.debug.middleware using the suggested edit:

<         try:
<             promise = next(root, info, **args)
<         except Exception as e:
<             return context.django_debug.on_resolve_error(e)
---
>         promise = next(root, info, **args)

and added that to my graphene settings:

GRAPHENE = {
    "SCHEMA": "helloworld.schema.schema",
    "MIDDLEWARE": ['helloworld.schema.DjangoDebugMiddleware']
}

This solved my issues when running in debug mode. Thanks again @zhoudaxia233 for your help with this!

@LVladymyr
Copy link

Version: graphene==3.2.1 graphene-django==v3.0.0 still actual.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants