捕获rails控制器中的所有异常

Nei*_*ard 87 ruby-on-rails

有没有办法在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
Run Code Online (Sandbox Code Playgroud)

谢谢

小智 193

您还可以定义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
Run Code Online (Sandbox Code Playgroud)

根据您的目标,您可能还需要考虑不基于每个控制器处理异常.相反,使用类似exception_handler gem的东西来一致地管理对异常的响应.作为奖励,此方法还将处理中间件层发生的异常,例如请求解析或应用程序未看到的数据库连接错误.该exception_notifier宝石也可能会感兴趣.

  • 这更方便,因为它允许以干燥的方式捕获异常. (4认同)
  • `rescue_from Exception`不是不好的做法吗?我的理解是,最好从"StandardError"中解救出来,因此不会捕获像`SyntaxError`和`LoadError`这样的东西. (2认同)

Chr*_*sen 91

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
Run Code Online (Sandbox Code Playgroud)

  • 从来没有捕获异常的规则? (36认同)
  • @JustinSkiles Catching Exception将捕获语法错误(以及中断信号).给我一个在生产代码中执行此操作的好方案.直接捕获信号我可以得到,但你需要明确地这样做,以明确你正在创建一个信号处理程序.抓住异常......糟糕,糟糕的主意.抓住你不应该抓住的东西. (10认同)
  • @RonLugge完全取决于手头的情况.应用"从不"作为经验法则是一个坏主意. (6认同)
  • 从Exception中拯救其中的几个常见案例之一是用于记录/报告目的,在这种情况下,您应该立即重新引发异常:http://stackoverflow.com/a/10048406/252346 (6认同)
  • 但是我如何才能仅在 `rescue =&gt; e` 块中捕获所有类型? (2认同)

moh*_*him 27

您可以按类型捕获异常:

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
Run Code Online (Sandbox Code Playgroud)

  • 小心不要直接从"例外"中解救; 见http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby (2认同)

Pre*_*ids 10

rescue 没有参数将拯救任何错误.

所以,你会想要:

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
Run Code Online (Sandbox Code Playgroud)

  • 陈旧的问题,但这个答案是不正确的.没有参数的rescue只处理StandardError http://robots.thoughtbot.com/rescue-standarderror-not-exception (8认同)