在application_controller.rb 中使用rescue_from 可以完成大部分工作:
01
class
ApplicationController
<
ActionController
::
Base
02
03 def self . rescue_errors
04 rescue_from Exception , :with => :render_error
05 rescue_from RuntimeError , :with => :render_error
06 rescue_from ActiveRecord :: RecordNotFound , :with => :render_not_found
07 rescue_from ActionController :: RoutingError , :with => :render_not_found
08 rescue_from ActionController :: UnknownController , :with => :render_not_found
09 rescue_from ActionController :: UnknownAction , :with => :render_not_found
10 end
11 rescue_errors unless Rails . env . development?
12
13 def render_not_found( exception = nil)
14 render :template => "errors/404" , :status => 404 , :layout => 'public'
15 end
16
17 def render_error( exception = nil)
18 render :template => "errors/500" , :status => 500 , :layout => 'public'
19 end
20
21 end
02
03 def self . rescue_errors
04 rescue_from Exception , :with => :render_error
05 rescue_from RuntimeError , :with => :render_error
06 rescue_from ActiveRecord :: RecordNotFound , :with => :render_not_found
07 rescue_from ActionController :: RoutingError , :with => :render_not_found
08 rescue_from ActionController :: UnknownController , :with => :render_not_found
09 rescue_from ActionController :: UnknownAction , :with => :render_not_found
10 end
11 rescue_errors unless Rails . env . development?
12
13 def render_not_found( exception = nil)
14 render :template => "errors/404" , :status => 404 , :layout => 'public'
15 end
16
17 def render_error( exception = nil)
18 render :template => "errors/500" , :status => 500 , :layout => 'public'
19 end
20
21 end
但 ActionController::RoutingError 在rails 3中却不能得到预期结果,因为Rails 3使用了Rack,Routing的异常在ActionDispatch::ShowExceptions 中处理了,而没有传入到application controller中
比较靠谱且简单的解决方案是在routes.rb最后加一条默认routes,指向到一个类似routing_error的action中,但需要加多一个action感觉不是很必要,得益于rails 3 routing的强大,可以很简单快捷方便的如此这般:
# make sure this rule is the last one
match '*path' => proc { | env| Rails . env . development? ? ( raise ActionController :: RoutingError , %{No route matches " #{ env [ "PATH_INFO" ] } "}) : ApplicationController . action( :render_not_found) . call( env) }
match '*path' => proc { | env| Rails . env . development? ? ( raise ActionController :: RoutingError , %{No route matches " #{ env [ "PATH_INFO" ] } "}) : ApplicationController . action( :render_not_found) . call( env) }
即可,在development中可以仍然查看详细的异常track back方便调试。
一些给力链接:
http://www.perfectline.ee/blog/custom-dynamic-error-pages-in-ruby-on-rails
http://helderribeiro.net/?p=366