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
相关产品推荐
相关产品推荐

