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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:12:34  来源:igfitidea点击:

Catch all exceptions in a rails controller

ruby-on-rails

提问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

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