【问题标题】:Rails rescue standard error doesn't get sent未发送 Rails 救援标准错误
【发布时间】:2018-04-12 15:41:10
【问题描述】:

我有一个控制器方法如下

def create
  @game = Game.create_new_game(game_params)
  render 'show', status: 200
rescue StandardError => e
  render json: {
    status: 500,
    error: e.to_s
   }
end

我添加了binding.pry,我可以在控制台中清楚地看到以下错误:

#<ActiveRecord::RecordInvalid: Validation failed: Name can't be blank, Duration can't be blank>

但它仍然将status:200 发送到客户端。是否应该以不同的方式处理错误?

编辑:

Game 中的create_new_game 方法

def self.create_new_game(prms)
  @player = Player.find(prms[:player].to_i)
  @game = @player.games.create!(
  name: prms[:name],
  duration: prms[:duration]
  )
  @game.save!
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 error-handling standard-error


    【解决方案1】:

    当记录无效时,ActiveRecord 通常不会引发异常。只有当您使用像.create! 这样的“bang”方法时才会引发异常。我们也不可能知道Game.create_new_game 内部发生了什么。例如,这些用于开发人员应该知道验证失败的种子文件或应该触发回滚的嵌套事务中。

    但是您所做的并不是一个好习惯,因为异常应该用于异常事件 - 而不是正常的控制流。

    您应该检查保存/更新记录的返回值并确定响应。

    def create
      @game = Game.create(game_params)
      if @game.save
        status: :created, location: @game
        # or
        render json: @game
      else
        render json: {
          status: 500,
          error: @game.errors.full_messages
        }
      end
    end
    

    【讨论】:

    • rescue StandardError =&gt; e 是“口袋妖怪异常处理”(必须全部捕获),它本身也是一种反模式。你应该只拯救你真正知道如何处理的异常,否则你最终会掩盖应用程序中的错误。
    • 我在问题中添加了create_new_game 方法。不过,我并没有真正捕捉到这里的异常,这是一个StandardError,所以它应该只捕捉到errors,对吧?
    • 所以基本上如果我需要检查错误,例如 player with id existsall the validations passed,那么我需要为所有这些添加单独的捕获?
    • @game.save 将运行模型中的所有验证,如果无效则返回 false。您可能想从基本的 Rails 教程开始,因为这是非常基本的东西。
    • 您可以通过在模型中添加验证来“检查具有 id 的玩家是否存在”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2013-08-31
    相关资源
    最近更新 更多