Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to handle errors in graphql mutations in rails

I'm using graphql for the first time in a rails application and i want to handle model validation errors.

My implementation is as follows:

Model code:

class User < ApplicationRecord
  validates :name, :phone_number, presence: true
end

mutation_type.rb

Types::MutationType = GraphQL::ObjectType.define do
  name "Mutation"

  field :createUser, Types::UserType do
    description 'Allows you to create a new user'

    argument :name, !types.String
    argument :phone_number, !types.String

    resolve ->(obj, args, ctx) {
      user = User.create!(args.to_h)
      user
    }
  end
end

user_type.rb

Types::UserType = GraphQL::ObjectType.define do
  name 'User'
  description 'Represents a user'

  field :id, !types.Int, 'The ID of a user'

  field :name, !types.String, 'The name of the user'

  field :phone_number, !types.String, 'The phone number of a user'

  field :errors, types[types.String], "Reasons the object couldn't be created or updated" do
    resolve -> (obj, args, ctx) { obj.errors.full_messages }
  end

end

Now in graphiql, when i try to create a user with invalid entry. It does not show the errors in the error field i have added in the user_type and it shows this

{
  "status": 422,
  "error": "Unprocessable Entity",
  "exception": "#<ActiveRecord::RecordInvalid: Validation failed: Phone number can't be blank>",
  "traces": {
    "Application Trace": [
      {
        "id": 15,
        "trace": "app/graphql/types/mutation_type.rb:11:in `block (3 levels) in <top (required)>'"
      },
      {
....     

Can someone suggest me what am I doing wrong or missing something?

like image 915
Ahmad hamza Avatar asked Oct 18 '25 01:10

Ahmad hamza


1 Answers

So i have changed the mutation file and used begin and rescue block to handle the errors and used save! to handle the errors:

Types::MutationType = GraphQL::ObjectType.define do
  name "Mutation"

  field :createUser, Types::UserType do
    description 'Allows you to create a new user'

    argument :name, !types.String
    argument :phone_number, !types.String

    resolve ->(obj, args, ctx) {
      begin
        user = User.new(args.to_h)
        user.save!
        user
      rescue ActiveRecord::RecordInvalid => err
        GraphQL::ExecutionError.new("#{user.errors.full_messages.join(', ')}")
      end
    }
  end
end

With this setup, i now have this response

{
  "data": {
    "createUser": null
  },
  "errors": [
    {
      "message": "Phone number can't be blank",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createUser"
      ]
    }
  ]
}

Which is quite detailed and can be used on the frontend easily.

like image 166
Ahmad hamza Avatar answered Oct 19 '25 16:10

Ahmad hamza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!