Graphql-ruby: "Cannot return null for non-nullable field CreateUserPayload.user"

Created on 20 Jul 2020  Â·  3Comments  Â·  Source: rmosolgo/graphql-ruby

I am getting this none descriptive error often when trying to create a user, I am able to figure out what the actual error is.

Error that graphql gives me:

{
  "data": {
    "createUser": null
  },
  "errors": [
    {
      "message": "Cannot return null for non-nullable field CreateUserPayload.user"
    }
  ]
}

The actual error that I get in my resolver is usually related to devise password requirements.

 user.errors.full_messages
=> ["Password is too short (minimum is 6 characters)"]

Here is my mutation:

class Mutations::CreateUser < Mutations::BaseMutation
  argument :name, String, required: true
  argument :email, String, required: true
  argument :password, String, required: true

  field :user, Types::UserType, null: false
  field :email, String, null: false
  field :password, String, null: false
  field :errors, [String], null: false


  def resolve(name:, email:, password:)
    binding.pry
    user = User.create({name: name, email: email, password: password})
    user.persisted? ? { user: user, errors: [] } : { user: nil, errors: user.errors.full_messages }
  end
end

I'd like to make this gem better and more useful. Anyone have any idea the best place look to get started on this fix ?

Versions
graphql (1.11.1)
rails (6.0.3.2)

GraphQL schema

Include relevant types and fields (in Ruby is best, in GraphQL IDL is ok).
Are you using interpreter? Any custom instrumentation, etc?

class Product < GraphQL::Schema::Object
  field :id, ID, null: false, hash_key: :id
  # …
end

class ApplicationSchema < GraphQL::Schema
  query QueryType
  # …
end

GraphQL query

mutation CreateUser {
  createUser (input: {
    name: "Don"
    email: "[email protected]"
    provider: "Facebook"
  }) {
    user {
      name
      email
    }
  }
}

Most helpful comment

Both of these worked great. Thank you!

All 3 comments

Hi! In your mutation configuration, you're telling clients that user will _never be nil_:

field :user, Types::UserType, null: false

But, when you return a value from a mutation, you're returning nil for user::

 { user: nil, ... }

This is illegal in GraphQL, and GraphQL _must_ handle the situation by _removing_ the invalid nil from the response.

If you want to return { user: nil, ...} when you have errors (which is a great idea), then you should update your mutation definition:

- field :user, Types::UserType, null: false
+ field :user, Types::UserType, null: true

That way, when there are errors, you can return user: nil.

How about addressing the issue that way?

Hello, I used GraphQL::ExecutionError.new " any error message " to throw any error message that I want here. I think maybe what you can do is like this:

  def resolve(name:, email:, password:)
    binding.pry
    user = User.create({name: name, email: email, password: password})
      if user.save? 
        user
      else 
        GraphQL::ExecutionError.new user.errors.full_messages.join(',')
      end
  end

Both of these worked great. Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gastonmorixe picture gastonmorixe  Â·  3Comments

rmosolgo picture rmosolgo  Â·  4Comments

rylanc picture rylanc  Â·  3Comments

jtippett picture jtippett  Â·  3Comments

jturkel picture jturkel  Â·  3Comments