如何处理rescue代码块内部再次抛出的异常
可行实现方案
最直接的方案是在原有rescue块内部嵌套begin-rescue结构,专门捕获处理二次异常,参考实现如下:
def func # 主业务逻辑 some code... rescue x, y, z => original_e # 第一层异常处理逻辑 begin # 可能触发二次异常的处理代码 do something... rescue => secondary_e # 二次异常专属处理逻辑 # 可自定义日志打印、降级返回、告警通知等操作 secondary_e.set_backtrace(secondary_e.backtrace + original_e.backtrace) if need_merge_backtrace handle_secondary_exception(secondary_e, original_e) # 处理完后可根据业务需要选择返回降级值,或者继续抛出异常 # raise secondary_e # 如需上层感知二次异常可打开此行 end end
扩展优化建议
- 可以根据场景需求,在内层rescue后指定要捕获的异常类型,和外层rescue的用法完全一致,避免无差别捕获所有异常
- 如果需要留存根因排查问题,可以将原始异常
original_e绑定到二次异常的cause属性,或者合并两个异常的调用栈后再打印日志 - 如果不需要上层感知二次异常,内层rescue处理完成后无需额外抛出,函数会正常返回或者执行后续逻辑
注意如果内层rescue没有显式抛出异常,二次异常会被完全消化在函数内部,上层调用方只会感知到第一层异常的处理结果,不会收到二次异常的通知。
内容的提问来源于stack exchange,提问作者CodeEnthusiast
相关产品推荐
相关产品推荐

