例外處理是幾乎每種程式語言都具備的功能,這個功能讓軟體工程師可以在程式出現非預期狀況的時候,能夠及時處理例外,並且設計處理每種例外的不同解決方式。
Ruby 能以區隔的 (compartmentalized) 方式處理例外的程式碼區塊。標示有
begin的程式碼區塊執行後若遇到例外,就將控制轉移至標示有rescue的錯誤處理程式碼區塊,若沒有出現例外,就不會使用rescue程式碼。
begin
  # 有可能發生例外的處理動作
rescue
  # 例外發生時的處理措施
ensure
  # 無論有沒有發生例外,這一段都一定會執行
end
而錯誤有百百種(如圖),其中最常見的 Syntax Error 以及 NoMethod Error。

其實例外處理也是一種流程控制,像是 fo..in 、 while 、 if..else 一樣。
begin 
  # 可能出現例外的程式碼
rescue SyntaxError
  # 出現SyntaxError時執行此行程式碼
rescue NoMethod Error
  # 出現ArgumentError時執行此行程式碼
end
但工程師都是小心的生物,並不是每一次程式碼都會遇到錯誤,特別是在簡單的程式碼,所以首先我們要先介紹如何手動產生例外,也就是 raise 方法。
def exception_example
  puts "例外開始前"
  raise  StandardError, "例外發生"
  puts "例外發生後"
end
exception_example 
# 印出以下內容
# 例外開始前
# `exception_example': 例外發生 (StandardError)
用 raise 來產生例外,如果你指定的引數只有一個,且為字串,raise 會建立RuntimeError 並將字串當作錯誤訊息,簡單的說, raise 方法(例外名稱:預設值為 RuntimeError , 例外訊息)。
def exception_example
  puts "例外開始前"
  raise "例外發生"
  puts "例外發生後"
end
exception_example 
# 印出以下內容
# 例外開始前
# `exception_example': 例外發生 (RuntimeError)
如果需要的話我們可以自訂例外類別,這裡有兩個原則:
class CoffeeTooWeakError < StandardError; end
raise(CoffeeTooWeakError, "coffee to water ratio too low")
藉由自訂例外的類別以指定的方式來辨識錯誤訊息,也許其他人透過程式碼就能選擇該如何處理這些錯誤的類型。
而當我們希望 rescue 能夠持續處理錯誤直到錯誤排除時可以用 retry 方法。
def greater_than_three(num)
  begin
    puts num    
    raise if num <= 3    # 引發例外,進入 rescue
  rescue
    num += 1
    retry
  ensure
    puts "已調整為#{num}"
  end
end
greater_than_three(1)
# 印出以下內容
# 1
# 2
# 3
# 4
# 已調整為4
最後,Ruby style :當例外的 begin 到 end 的範圍剛好就是整個方法的範圍,我們可以省略 begin 跟 end。
def greater_than_three(num)
  puts num    
  raise if num <= 3     # 引發例外,進入 rescue
  rescue
    num += 1
    retry
  ensure
    puts "已調整為#{num}"
end
此文同步刊登於CJ-Han的網站