如何处理rails中graphql突变的错误

时间:2018-02-10 18:34:39

标签: ruby-on-rails ruby graphql

我在rails应用程序中第一次使用graphql,我想处理模型验证错误。我指的是this页面,但这对我不起作用。

我的实施如下:

型号代码:

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

现在在graphiql,当我尝试创建一个无效条目的用户时。它没有在errors中添加的错误字段中显示user_type并显示此

{
  "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)>'"
      },
      {
....     

有人可以告诉我,我做错了什么或遗失了什么?

3 个答案:

答案 0 :(得分:3)

所以我更改了变异文件并使用begin and rescue块来处理错误并使用了save!处理错误:

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

通过此设置,我现在有了这个回复

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

这是非常详细的,可以轻松地在前端使用。

答案 1 :(得分:0)

几天前我遇到了同样的情况。 IMO最好将错误属性分开,以便您可以在前端适当地显示错误。所以我创建了一个通用的ErrorType并在几个地方使用。

  

错误类型

ErrorType = GraphQL::ObjectType.define do
  name "GenericErrormessage"
  description "Displays field wise errors "

  field :field_name do
    type !types.String
    resolve -> (obj, args, ctx) do
      obj[0].to_s.split('.')[-1]
    end
  end

  field :field_errors do
    type types[types.String]
    resolve -> (obj, args, ctx) do
      obj[-1]
    end
  end

end

并且像这样使用它。

field :errors do
  type types[ErrorType]
    resolve ->(obj, args, ctx) {
      obj.errors.messages
    }
  end
end

如果错误字段长度大于0.则意味着对象创建失败并且可以显示相应的错误。希望这会对你有所帮助。

答案 2 :(得分:0)

你是否尝试过使用没有爆炸的方法?

system("pause")代替User.create(args.to_h)

创造!方法抛出异常