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
}
}
}
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!
Most helpful comment
Both of these worked great. Thank you!