异常
2018-02-24 16:10 更新
-
使用
fail
方法来抛出异常。仅在捕捉到异常时使用raise
来重新抛出异常(因为没有失败,所以只是显式地有目的性地抛出一个异常)begin fail 'Oops'; rescue => error raise if error.message != 'Oops' end
-
如果
fail/raise
只有两个参数,无需显性指定RuntimeError
。# 差 fail RuntimeError, 'message' # 好——默认就是 RuntimeError fail 'message'
-
将异常类和消息作为参数给
fail/raise
,而不是异常类的的实例。# 差 fail SomeException.new('message') # 无法使用 `fail SomeException.new('message'), backtrace`. # 好 fail SomeException, 'message' # 可以使用 `fail SomeException, 'message', backtrace`.
-
永远不要从
ensure
区块返回。如果你显式地从ensure
区块中的一个方法返回,那么这方法会如同没有异常般的返回。实际上,异常会被默默丢掉。def foo begin fail ensure return 'very bad idea' end end
-
尽可能使用隐式的
begin
区块。# 差 def foo begin # 此处放主要逻辑 rescue # 错误处理放在此处 end end # 好 def foo # 此处放主要逻辑 rescue # 错误处理放在此处 end
-
通过 contingency 方法 (一个由 Avdi Grimm 创造的词) 来减少
begin
区块的使用。# 差 begin something_that_might_fail rescue IOError # 处理 IOError end begin something_else_that_might_fail rescue IOError # 处理 IOError end # 好 def with_io_error_handling yield rescue IOError # 处理 IOError end with_io_error_handling { something_that_might_fail } with_io_error_handling { something_else_that_might_fail }
-
不要抑制异常。
begin # 这里发生了一个异常 rescue SomeError # 拯救子句完全没有做事 end # 差 do_something rescue nil
-
避免使用
rescue
的修饰符形式。# 差 - 这捕捉了所有的 StandardError 异常。 do_something rescue nil
-
不要为了控制流程而使用异常。
# 差 begin n / d rescue ZeroDivisionError puts 'Cannot divide by 0!' end # 好 if d.zero? puts 'Cannot divide by 0!' else n / d end
-
避免救援
Exception
类别。这会把信号困住,并呼叫exit
,导致你需要kill -9
进程。# 差 begin # 呼叫 exit 及杀掉信号会被捕捉(除了 kill -9) exit rescue Exception puts "you didn't really want to exit, right?" # 异常处理 end # 好 begin # 一个不明确的 rescue 子句捕捉的是 StandardError, # 而不是许多编程者所设想的 Exception。 rescue => e # 异常处理 end # 也好 begin # 这里发生一个异常 rescue StandardError => e # 异常处理 end
-
把较具体的异常放在救援串连的较上层,不然它们永远不会被拯救。
# 差 begin # 一些代码 rescue Exception => e # 一些处理 rescue StandardError => e # 一些处理 end # 好 begin # 一些代码 rescue StandardError => e # 一些处理 rescue Exception => e # 一些处理 end
-
在
ensure
区块中释放你的程式的外部资源。f = File.open('testfile') begin # .. 处理 rescue # .. 错误处理 ensure f.close unless f.nil? end
- 倾向使用标准库的异常类而不是导入新的异常类。
以上内容是否对您有帮助:
← 类别
更多建议: