Skip to content
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

Returning bool from mutation causes exception. #507

Open
baseplate-admin opened this issue Mar 22, 2024 · 6 comments
Open

Returning bool from mutation causes exception. #507

baseplate-admin opened this issue Mar 22, 2024 · 6 comments
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed

Comments

@baseplate-admin
Copy link
Contributor

baseplate-admin commented Mar 22, 2024

Describe the Bug

Hi i have a mutation like this:

@strawberry.type
class UserMutation:
    @strawberry_django.mutation()
    def login(self, info: Info, data: UserLoginInput) -> TokenType | None:
        request: HttpRequest = cast(HttpRequest, info.context["request"])
        user = django_authenticate(request, username=data.username, password=data.password)
        if user is not None:
            django_login(request, user)
            token, _ = Token.objects.get_or_create(user=user.pk)
            return token

    @strawberry_django.mutation()
    def logout(self, info: Info, data: TokenType) -> bool:
        pass

and it raises an error like this:

C:\Programming\CoreProject\backend\django_core\apps\gql\mutations\user.py changed, reloading.
Watching for file changes with StatReloader
Performing system checks...

Traceback (most recent call last):
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\definition.py", line 808, in fields
    fields = resolve_thunk(self._fields)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\definition.py", line 300, in resolve_thunk
    return thunk() if callable(thunk) else thunk
           ^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 521, in <lambda>
    fields=lambda: self.get_graphql_fields(object_type),
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 378, in get_graphql_fields
    return _get_thunk_mapping(
           ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 136, in _get_thunk_mapping
    thunk_mapping[name_converter(field)] = field_converter(
                                           ^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 332, in from_field
    graphql_arguments[argument_name] = self.from_argument(argument)
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 197, in from_argument
    return GraphQLArgument(
           ^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\definition.py", line 662, in __init__
    raise TypeError("Argument type must be a GraphQL input type.")
TypeError: Argument type must be a GraphQL input type.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1073, in _bootstrap_inner
    self.run()
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1010, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\management\commands\runserver.py", line 133, in inner_run
    self.check(display_num_errors=True)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\management\base.py", line 485, in check
    all_issues = checks.run_checks(
                 ^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
    return check_resolver(resolver)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
    return check_method()
           ^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\resolvers.py", line 516, in check
    for pattern in self.url_patterns:
                   ^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\utils\functional.py", line 47, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\resolvers.py", line 735, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                       ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\utils\functional.py", line 47, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\resolvers.py", line 728, in urlconf_module
    return import_module(self.urlconf_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "C:\Programming\CoreProject\backend\django_core\core\urls.py", line 44, in <module>
    path("graphql/", include("apps.gql.urls")),
                     ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\conf.py", line 38, in include
    urlconf_module = import_module(urlconf_module)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "C:\Programming\CoreProject\backend\django_core\apps\gql\urls.py", line 3, in <module>
    from .schema import schema as schema
  File "C:\Programming\CoreProject\backend\django_core\apps\gql\schema.py", line 27, in <module>
    schema = strawberry.Schema(
             ^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema.py", line 143, in __init__
    self._schema = GraphQLSchema(
                   ^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\schema.py", line 226, in __init__
    collect_referenced_types(mutation)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\schema.py", line 432, in collect_referenced_types
    for field in named_type.fields.values():
                 ^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\functools.py", line 995, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\definition.py", line 811, in fields
    raise cls(f"{self.name} fields cannot be resolved. {error}") from error
TypeError: Mutation fields cannot be resolved. Argument type must be a GraphQL input type.

System Information

  • Operating system: Windows 11
  • Strawberry version (if applicable): 0.220.0

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@bellini666
Copy link
Member

Hi @baseplate-admin ,

It is probably not the bool that is causing the issue, instead it is the data: TokenType you are passing to logout

Any argument for any resolver needs to be an input type. Considering that you are returning TokenType | None in the login mutation, I'm assuming it is a type and not an input type.

@baseplate-admin

This comment was marked as outdated.

@baseplate-admin
Copy link
Contributor Author

I got this new exception if i return bool:

C:\Programming\CoreProject\backend\django_core\apps\gql\mutations\user.py changed, reloading.
Watching for file changes with StatReloader
Performing system checks...

Traceback (most recent call last):
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1073, in _bootstrap_inner
    self.run()
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1010, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\management\commands\runserver.py", line 133, in inner_run       
    self.check(display_num_errors=True)
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\management\base.py", line 485, in check
    all_issues = checks.run_checks(
                 ^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
    return check_resolver(resolver)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
    return check_method()
           ^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\resolvers.py", line 516, in check
    for pattern in self.url_patterns:
                   ^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\utils\functional.py", line 47, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\resolvers.py", line 735, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                       ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\utils\functional.py", line 47, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\resolvers.py", line 728, in urlconf_module
    return import_module(self.urlconf_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "C:\Programming\CoreProject\backend\django_core\core\urls.py", line 44, in <module>
    path("graphql/", include("apps.gql.urls")),
                     ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\django\urls\conf.py", line 38, in include
    urlconf_module = import_module(urlconf_module)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "C:\Programming\CoreProject\backend\django_core\apps\gql\urls.py", line 3, in <module>
    from .schema import schema as schema
  File "C:\Programming\CoreProject\backend\django_core\apps\gql\schema.py", line 27, in <module>
    schema = strawberry.Schema(
             ^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema.py", line 162, in __init__
    raise error.__cause__ from None
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\definition.py", line 808, in fields
    fields = resolve_thunk(self._fields)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\graphql\type\definition.py", line 300, in resolve_thunk
    return thunk() if callable(thunk) else thunk
           ^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 521, in <lambda>
    fields=lambda: self.get_graphql_fields(object_type),
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 378, in get_graphql_fields     
    return _get_thunk_mapping(
           ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 136, in _get_thunk_mapping     
    thunk_mapping[name_converter(field)] = field_converter(
                                           ^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 319, in from_field
    self.from_maybe_optional(
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 748, in from_maybe_optional    
    return GraphQLNonNull(self.from_type(type_))
                          ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 773, in from_type
    return self.from_union(type_)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\baseplate-admin\AppData\Local\pypoetry\Cache\virtualenvs\coreproject-CGb-jJ-B-py3.12\Lib\site-packages\strawberry\schema\schema_converter.py", line 791, in from_union
    raise InvalidUnionTypeError(union_name, type_, union_definition=union)
strawberry.exceptions.invalid_union_type.InvalidUnionTypeError: Type `bool` cannot be used in a GraphQL Union

@bellini666
Copy link
Member

That's indeed related to bool.

Are you passing handle_django_errors=True to the mutation (or maybe you have MUTATIONS_DEFAULT_HANDLE_ERRORS=True in your settings)?

If so, as you can see in the docs, the mutation will automatically create a union of your return type and OperationInfo. The issue with that is that graphql doesn't allow unions of types with scalars, meaning you can't return a bool/int/str/etc in there

@baseplate-admin
Copy link
Contributor Author

Yep, good catch.

The issue was with handle_django_errors=True.


but should this be an issue?

@bellini666
Copy link
Member

but should this be an issue?

Probably the error can be better, and the documentation can also be improved 😅

@bellini666 bellini666 added documentation Improvements or additions to documentation help wanted Extra attention is needed and removed bug Something isn't working labels Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants