【问题标题】:rails rescue_from ScriptErrorrails rescue_from ScriptError
【发布时间】:2016-08-29 17:52:22
【问题描述】:

根据Exception的家谱。 SyntaxErrorScriptError 的孩子

我希望在我的 rails 应用程序中处理 Syntax 和/或 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

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

【问题讨论】:

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


    【解决方案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
    

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

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

    【讨论】:

      【解决方案2】:

      谢谢!

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

      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
      

      【讨论】:

      • 哇,有趣。它甚至可以在生产环境中工作吗?我认为 Rails 在开始生产时会立即加载所有文件,所以起初我认为这仅适用于开发。但不确定。
      猜你喜欢
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-20
      • 2011-07-12
      • 2013-10-12
      相关资源
      最近更新 更多