Ruby-on-rails 捕获 rails 控制器中的所有异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3694153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Catch all exceptions in a rails controller
提问by Neigaard
Is there a way to catch all uncatched exceptions in a rails controller, like this:
有没有办法在 rails 控制器中捕获所有未捕获的异常,如下所示:
def delete
schedule_id = params[:scheduleId]
begin
Schedules.delete(schedule_id)
rescue ActiveRecord::RecordNotFound
render :json => "record not found"
rescue ActiveRecord::CatchAll
#Only comes in here if nothing else catches the error
end
render :json => "ok"
end
Thank you
谢谢
回答by BOFH
You can also define a rescue_from method.
您还可以定义一个rescue_from 方法。
class ApplicationController < ActionController::Base
rescue_from ActionController::RoutingError, :with => :error_render_method
def error_render_method
respond_to do |type|
type.xml { render :template => "errors/error_404", :status => 404 }
type.all { render :nothing => true, :status => 404 }
end
true
end
end
Depending on what your goal is, you may also want to consider NOT handling exceptions on a per-controller basis. Instead, use something like the exception_handlergem to manage responses to exceptions consistently. As a bonus, this approach will also handle exceptions that occur at the middleware layer, like request parsing or database connection errors that your application does not see. The exception_notifiergem might also be of interest.
根据您的目标,您可能还需要考虑不处理每个控制器的异常。相反,使用类似exception_handlergem 的东西来一致地管理对异常的响应。作为奖励,此方法还将处理发生在中间件层的异常,例如您的应用程序看不到的请求解析或数据库连接错误。该exception_notifier宝石也可能会感兴趣。
回答by Chris Johnsen
begin
# do something dodgy
rescue ActiveRecord::RecordNotFound
# handle not found error
rescue ActiveRecord::ActiveRecordError
# handle other ActiveRecord errors
rescue # StandardError
# handle most other errors
rescue Exception
# handle everything else
raise
end
回答by mohamed-ibrahim
You can catch exceptions by type:
您可以按类型捕获异常:
rescue_from ::ActiveRecord::RecordNotFound, with: :record_not_found
rescue_from ::NameError, with: :error_occurred
rescue_from ::ActionController::RoutingError, with: :error_occurred
# Don't resuce from Exception as it will resuce from everything as mentioned here "http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby" Thanks for @Thibaut Barrère for mention that
# rescue_from ::Exception, with: :error_occurred
protected
def record_not_found(exception)
render json: {error: exception.message}.to_json, status: 404
return
end
def error_occurred(exception)
render json: {error: exception.message}.to_json, status: 500
return
end
回答by PreciousBodilyFluids
rescuewith no arguments will rescue any error.
rescue没有参数将挽救任何错误。
So, you'll want:
所以,你会想要:
def delete
schedule_id = params[:scheduleId]
begin
Schedules.delete(schedule_id)
rescue ActiveRecord::RecordNotFound
render :json => "record not found"
rescue
#Only comes in here if nothing else catches the error
end
render :json => "ok"
end
回答by BF4
Actually, if you really want to catch everything, you just create your own exceptions app, which let's you customize the behavior that is usually handled by the PublicExceptions middleware: https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
实际上,如果您真的想捕获所有内容,只需创建自己的异常应用程序,即可自定义通常由 PublicExceptions 中间件处理的行为:https: //github.com/rails/rails/blob/4-2 -stable/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
- location in stack https://github.com/rails/rails/blob/4-2-stable/railties/lib/rails/application/default_middleware_stack.rb#L98-L99
- configuring https://github.com/rails/rails/blame/4-2-stable/guides/source/configuring.md#L99
- which can be as easy as using the routes http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/or a custom controller (but see https://github.com/rails/rails/pull/17815for reasons not to use the routes)
- 堆栈中的位置https://github.com/rails/rails/blob/4-2-stable/railties/lib/rails/application/default_middleware_stack.rb#L98-L99
- 配置https://github.com/rails/rails/blame/4-2-stable/guides/source/configuring.md#L99
- 这可以像使用路由一样简单http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/或自定义控制器(但请参阅https://github.com/rails/rails/pull/17815不使用路线的原因)
A bunch of the other answers share gems that do this for you, but there's really no reason you can't just look at them and do it yourself.
一堆其他答案分享了为你做这件事的宝石,但真的没有理由你不能只看它们并自己做。
A caveat: make sure you never raise an exception in your exception handler. Otherwise you get an ugly FAILSAFE_RESPONSE https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L4-L22
警告:确保您永远不会在异常处理程序中引发异常。否则你会得到一个丑陋的 FAILSAFE_RESPONSE https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L4-L22
BTW, the behavior in the controller comes from rescuable: https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51
顺便说一句,控制器中的行为来自rescuable:https: //github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51

