rails rescue_from ScriptError

时间:2016-05-04 10:34:18

标签: ruby-on-rails ruby exception-handling ruby-2.2

根据Exception的家谱。 SyntaxErrorScriptError

的孩子

我希望在我的rails应用程序中处理语法和/或ScriptError。

Exception
    NoMemoryError
    ScriptError
        LoadError
        NotImplementedError
        SyntaxError
    SignalException
        Interrupt
    StandardError
        ArgumentError
        IOError
            EOFError
        IndexError
            StopIteration
        LocalJumpError
        NameError
            NoMethodError
        RangeError
            FloatDomainError
        RegexpError
        RuntimeError
        SecurityError
        SystemCallError
        SystemStackError
        ThreadError
        TypeError
        ZeroDivisionError
    SystemExit
    fatal

我做了:

rescue_from ScriptError, :with => :notify_on_landing_page

但没有奏效。

屏幕上出现错误: SyntaxError in Bc::Muse::User::ProfileController#show

我创建了一个明确的语法错误,它应该优雅地拯救它并做我想做的事情。

2 个答案:

答案 0 :(得分:1)

不幸的是,我不认为它是这样运作的。

仅在rescue_from的例外情况下,只有在请求处理期间创建控制器实例后才能执行(请参阅源代码herehere)。在给定控制器和依赖类/模块的自动加载期间,您的SyntaxError可能更早提升。因此,除非你试图在执行控制器动作期间从加载代码的语法错误中解脱出来,否则你很不幸,我很害怕。

测试:当您在控制器操作中明确load文件时出现语法错误,并且rescue_from将按预期工作:

class MyController < ApplicationController
  rescue_from(::SyntaxError) { Rails.logger.error "SYNTAX ERROR!" }

  def index
    load "#{Rails.root}/test.rb"
  end
end

如果在rails根目录中保存test.rb文件并在其中添加故意语法错误,您将看到rescue_from正确处理异常,并且日志中将显示错误消息文件。

另一方面,如果您查看SyntaxError的完整堆栈跟踪,您可能会发现它甚至没有达到请求处理的ActionController方法。

答案 1 :(得分:0)

谢谢!

我添加了一个中间件来实现这一目标。

class RescueSyntaxError
  def initialize(app)
    @app = app
  end

  def call(env)
    @app.call(env)
  rescue SyntaxError => error

    request = Rack::Request.new(env)
    session = request.env['rack.session']
    params = request.params

    if session.try(:[], :user_object)
      ##Do validation stuff
      ...
      [302, {'Location' => '/'}, []]
    end
  end
end