为什么`rescue Exception => 是不好的风格?Ruby 中的 e`? [英] Why is it bad style to `rescue Exception => e` in Ruby?

查看:16
本文介绍了为什么`rescue Exception => 是不好的风格?Ruby 中的 e`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ryan Davis 的 Ruby QuickRef 说(没有解释):><块引用>

不要拯救异常.曾经.否则我会刺伤你.

为什么不呢?正确的做法是什么?

解决方案

TL;DR:使用 StandardError 代替常规异常捕获.当重新引发原始异常时(例如,当救援仅记录异常时),救援 Exception 可能没问题.

<小时>

ExceptionRuby 异常层次结构 的根,所以当你拯救异常你从一切中拯救出来,包括子类,比如SyntaxErrorLoadErrorInterrupt.

Rescuing Interrupt 阻止用户使用 CTRLC 退出程序.

拯救SignalException 会阻止程序正确响应信号.除非通过 kill -9 否则它是不可杀死的.

拯救 SyntaxError 意味着失败的 eval 会默默地这样做.

所有这些都可以通过运行这个程序来显示,并尝试 CTRLCkill 它:

循环做开始睡觉 1评估djsakru3924r9eiuorwju3498 += 5u84fior8u8t4ruyf8ihiure"救援异常我拒绝失败或被阻止!"结尾结尾

Rescuing from Exception 甚至不是默认设置.做

开始#冰山!救援#救生艇结尾

不从Exception 中拯救,它从StandardError 中拯救.您通常应该指定比默认的 StandardError 更具体的内容,但是从 Exception 中拯救扩大范围而不是缩小范围,并且可能会产生灾难性的结果并使寻找错误变得极其困难.

<小时>

如果您确实想从 StandardError 中拯救出来,并且需要一个带有异常的变量,则可以使用以下形式:

开始#冰山!救援 =>电子#救生艇结尾

相当于:

开始#冰山!救援标准错误 =>电子#救生艇结尾

<小时>

Exception 中拯救出来的少数几种常见情况之一是用于日志记录/报告目的,在这种情况下,您应该立即重新引发异常:

开始#冰山?救援异常 =>电子# 做一些日志记录提高#没有足够的救生艇;)结尾

Ryan Davis’s Ruby QuickRef says (without explanation):

Don’t rescue Exception. EVER. or I will stab you.

Why not? What’s the right thing to do?

解决方案

TL;DR: Use StandardError instead for general exception catching. When the original exception is re-raised (e.g. when rescuing to log the exception only), rescuing Exception is probably okay.


Exception is the root of Ruby's exception hierarchy, so when you rescue Exception you rescue from everything, including subclasses such as SyntaxError, LoadError, and Interrupt.

Rescuing Interrupt prevents the user from using CTRLC to exit the program.

Rescuing SignalException prevents the program from responding correctly to signals. It will be unkillable except by kill -9.

Rescuing SyntaxError means that evals that fail will do so silently.

All of these can be shown by running this program, and trying to CTRLC or kill it:

loop do
  begin
    sleep 1
    eval "djsakru3924r9eiuorwju3498 += 5u84fior8u8t4ruyf8ihiure"
  rescue Exception
    puts "I refuse to fail or be stopped!"
  end
end

Rescuing from Exception isn't even the default. Doing

begin
  # iceberg!
rescue
  # lifeboats
end

does not rescue from Exception, it rescues from StandardError. You should generally specify something more specific than the default StandardError, but rescuing from Exception broadens the scope rather than narrowing it, and can have catastrophic results and make bug-hunting extremely difficult.


If you have a situation where you do want to rescue from StandardError and you need a variable with the exception, you can use this form:

begin
  # iceberg!
rescue => e
  # lifeboats
end

which is equivalent to:

begin
  # iceberg!
rescue StandardError => e
  # lifeboats
end


One of the few common cases where it’s sane to rescue from Exception is for logging/reporting purposes, in which case you should immediately re-raise the exception:

begin
  # iceberg?
rescue Exception => e
  # do some logging
  raise # not enough lifeboats ;)
end

这篇关于为什么`rescue Exception => 是不好的风格?Ruby 中的 e`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆