單個異常使用 fail 關(guān)鍵字僅僅當(dāng)捕獲一個異常并且反復(fù)拋出這個異常(因為這里你不是失敗,而是準(zhǔn)確的并且故意拋出一個異常)。
begin
fail 'Oops'
rescue => error
raise if error.message != 'Oops'
end
不要為 fail/raise 指定準(zhǔn)確的 RuntimeError。
# bad
fail RuntimeError, 'message'
# good - signals a RuntimeError by default
fail 'message'
寧愿提供一個異常類和一條消息作為 fail/raise 的兩個參數(shù),而不是一個異常實例。
# bad
fail SomeException.new('message')
# Note that there is no way to do `fail SomeException.new('message'), backtrace`.
# good
fail SomeException, 'message'
# Consistent with `fail SomeException, 'message', backtrace`.
不要在 ensure 塊中返回。如果你明確的從 ensure 塊中的某個方法中返回,返回將會優(yōu)于任何拋出的異常,并且盡管沒有異常拋出也會返回。實際上異常將會靜靜的溜走。
def foo
begin
fail
ensure
return 'very bad idea'
end
end
Use implicit begin blocks when possible.如果可能使用隱式 begin 代碼塊。
# bad
def foo
begin
# main logic goes here
rescue
# failure handling goes here
end
end
# good
def foo
# main logic goes here
rescue
# failure handling goes here
end
通過 contingency methods 偶然性方法。 (一個由 Avdi Grimm 創(chuàng)造的詞) 來減少 begin 區(qū)塊的使用。
# bad
begin
something_that_might_fail
rescue IOError
# handle IOError
end
begin
something_else_that_might_fail
rescue IOError
# handle IOError
end
# good
def with_io_error_handling
yield
rescue IOError
# handle IOError
end
with_io_error_handling { something_that_might_fail }
with_io_error_handling { something_else_that_might_fail }
不要抑制異常輸出。
# bad
begin
# an exception occurs here
rescue SomeError
# the rescue clause does absolutely nothing
end
# bad
do_something rescue nil
避免使用 rescue 的修飾符形式。
# bad - this catches exceptions of StandardError class and its descendant classes
read_file rescue handle_error($!)
# good - this catches only the exceptions of Errno::ENOENT class and its descendant classes
def foo
read_file
rescue Errno::ENOENT => ex
handle_error(ex)
end
不要用異常來控制流。
# bad
begin
n / d
rescue ZeroDivisionError
puts "Cannot divide by 0!"
end
# good
if d.zero?
puts "Cannot divide by 0!"
else
n / d
end
應(yīng)該總是避免攔截(最頂級的) Exception 異常類。這里(ruby自身)將會捕獲信號并且調(diào)用 exit,需要你使用 kill -9 殺掉進(jìn)程。
# bad
begin
# calls to exit and kill signals will be caught (except kill -9)
exit
rescue Exception
puts "you didn't really want to exit, right?"
# exception handling
end
# good
begin
# a blind rescue rescues from StandardError, not Exception as many
# programmers assume.
rescue => e
# exception handling
end
# also good
begin
# an exception occurs here
rescue StandardError => e
# exception handling
end
將更具體的異常放在救援(rescue)鏈的上方,否則他們將不會被救援。
# bad
begin
# some code
rescue Exception => e
# some handling
rescue StandardError => e
# some handling
end
# good
begin
# some code
rescue StandardError => e
# some handling
rescue Exception => e
# some handling
end
在 ensure 區(qū)塊中釋放你程式獲得的外部資源。
f = File.open('testfile')
begin
# .. process
rescue
# .. handle error
ensure
f.close unless f.nil?
end
除非必要, 盡可能使用 Ruby 標(biāo)準(zhǔn)庫中異常類,而不是引入一個新的異常類。(而不是派生自己的異常類)
您可能感興趣的文章:- 詳解Ruby中的異常
- ruby 異常處理:ensure
- ruby 異常處理:rescue