正常在實作 Rails 的 show action 時都會是:
@post = Post.find(params[:id])
根據傳入的 id 用 find 去找到物件,但若沒有這個 id 的紀錄呢?就會跑出 ActiveRecord::RecordNotFound 的錯誤,是錯誤喔不是 warning 而已
但其實這事情也不是挺嚴重,可能就不小心打錯 ID 或是被爬蟲亂爬導致,不算是 bug,只是沒有特別處理(尤當裝 rollbar 後,一直累計噴錯也不是辦法...)
那 rescue_from 是 ActiveController 裡面非常有用的一個函式,可以在一個 controller 的範圍內將某個 error 都 catch 起來統一處理,尤其是 ActiveRecord::RecordNotFound 這個~
class PostController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
private
def record_not_found
message = "Post with ID #{params[:id]} not found."
logger.error message
redirect_to not_found_url, info: message
end
end
依照上述作法,當遇到 ActiveRecord::RecordNotFound 時就會自動記錄哪個 id 找不到 Post,並 redirect 到相對應告知找不到記錄的頁面。當然 rescue_from 本身也有 block 供使用,可以改成:
class PostController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found do |exception|
message = "Post with ID #{params[:id]} not found."
logger.error message
redirect_to not_found_url, info: message
end
end
如果是一般自己寫的 class 想要 handle 特殊例外狀況的話~可以直接 mixin ActiveSupport::Rescuable 就好
class Foo
include ActiveSupport::Rescuable
end