好久不寫了,blog密碼差點忘掉。。。

網上有好多處理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原始碼看來很有好處。