網上有好多處理error的方法,新建一個controller,修改route可以自定義統一的error處理頁面。下面我有個方法,和大家分享一下:
檢視Rails原始碼 :actionpack/lib/action_controller/rescue.rb:
def rescue_action_in_public(exception) #:doc:
render_optional_error_file response_code_for_rescue(exception)
end
我們可以重寫這個方法,application.rb中:
def rescue_action_in_public(exception)
case exception.class.name
when
`ActiveRecord::RecordNotFound`,`::ActionController::UnknownAction`,`::ActionController::RoutingError`
RAILS_DEFAULT_LOGGER.error(“404 displayed”)
render(:file => “#{RAILS_ROOT}/public/404.html”, :status => “404 Error”)
else
RAILS_DEFAULT_LOGGER.error(“500 displayed”)
render(:file => “#{RAILS_ROOT}/public/500.html”, :status => “500 Error”)
end
end
然後注意,這裡rescue_action_in_public方法是隻對production環境有用的,在developmen模式下不起作用(這裡感謝Hozaka兄弟的指教)。
我們繼續看原始碼:
def rescue_action(exception)
log_error(exception) if logger
erase_results if performed?
# Let the exception alter the response if it wants.
# For example, MethodNotAllowed sets the Allow header.
if exception.respond_to?(:handle_response!)
exception.handle_response!(response)
end
if consider_all_requests_local || local_request?
rescue_action_locally(exception)
else
rescue_action_in_public(exception)
end
end
注
意最後那個if語句,這裡是判斷request是否來自本地的請求,當為development下,被rescue_action_locally方法處
理exception,但是我們如果在application裡重寫rescue_action_locally方法,就可以自由的測試開發了。如下:
#for development
def rescue_action_locally(exception)
case exception.class.name
when `ActiveRecord::RecordNotFound`,`::ActionController::UnknownAction`,`::ActionController::RoutingError`
RAILS_DEFAULT_LOGGER.error(“404 displayed”)
render(:file => “#{RAILS_ROOT}/public/404.html”, :status => “404 Error”)
else
RAILS_DEFAULT_LOGGER.error(“500 displayed”)
render(:file => “#{RAILS_ROOT}/public/500.html”, :status => “500 Error”)
end
end
看Rails原始碼看來很有好處。