You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails API 捕获异常添加错误信息后如何继续执行后续逻辑

问题解答

可以实现捕获异常后继续执行后续逻辑,且save!抛出ActiveRecord::RecordInvalid异常时,Rails已经跑完了所有校验规则,把所有校验错误都填充到了@model.errors对象中,你无需额外收集。


最优实现方案:改用无感叹号的save方法

不需要依赖异常捕获处理校验失败场景,无感叹号的save方法校验失败时不会抛出异常,会自动填充所有错误到errors对象,返回布尔值代表保存结果,代码改后如下:

class ModelSaver
  include ActiveModel::Validations

  attr_reader :model

  def initialize(params)
    @params = params
  end

  def errors
    @model&.errors || ActiveModel::Errors.new(self)
  end

  def save_model
    @model ||= Model.new(params)
    @model.name = nil

    if @model.save
      # 此处写保存成功后的后续逻辑
      return true
    end
    
    # 此处写校验失败后的后续逻辑,@model.errors已经包含所有校验错误
    # 可直接通过 @model.errors.full_messages 查看所有错误提示
    false
  end

  private

  attr_reader :params
end

若必须使用save!的调整方案

如果你的场景需要捕获数据库层面的异常(比如唯一索引冲突等ActiveRecord校验无法覆盖的错误),可以保留异常捕获逻辑,调整如下:

def save_model
  @model ||= Model.new(params)
  @model.name = nil
  @model.save!
  # 保存成功的后续逻辑
  true
rescue ActiveRecord::RecordInvalid => _e
  # 此时@model.errors已经包含所有校验错误,无需额外把异常信息加到base避免冗余
  # 此处写校验失败后的后续逻辑
  false
rescue ActiveRecord::RecordNotSaved, ActiveRecord::RecordNotUnique => e
  # 处理非校验类的保存失败异常
  @model.errors.add(:base, e.message)
  # 此处写对应场景的后续逻辑
  false
end

注意:默认Rails校验会执行所有规则收集全部错误,如果你有自定义校验配置了abort_if提前终止,删除该配置即可收集全部错误。

内容的提问来源于stack exchange,提问作者N0ne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:39:02