單個(gè)異常使用 fail 關(guān)鍵字僅僅當(dāng)捕獲一個(gè)異常并且反復(fù)拋出這個(gè)異常(因?yàn)檫@里你不是失敗,而是準(zhǔn)確的并且故意拋出一個(gè)異常)。
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'
寧愿提供一個(gè)異常類(lèi)和一條消息作為 fail/raise 的兩個(gè)參數(shù),而不是一個(gè)異常實(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 塊中的某個(gè)方法中返回,返回將會(huì)優(yōu)于任何拋出的異常,并且盡管沒(méi)有異常拋出也會(huì)返回。實(shí)際上異常將會(huì)靜靜的溜走。
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
通過(guò) contingency methods 偶然性方法。 (一個(gè)由 Avdi Grimm 創(chuàng)造的詞) 來(lái)減少 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
不要用異常來(lái)控制流。
# 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)該總是避免攔截(最頂級(jí)的) Exception 異常類(lèi)。這里(ruby自身)將會(huì)捕獲信號(hào)并且調(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)鏈的上方,否則他們將不會(huì)被救援。
# 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)庫(kù)中異常類(lèi),而不是引入一個(gè)新的異常類(lèi)。(而不是派生自己的異常類(lèi))
您可能感興趣的文章:- 詳解Ruby中的異常
- ruby 異常處理:ensure
- ruby 異常處理:rescue