【问题标题】:Rescue all errors of a specific type inside a module抢救模块内特定类型的所有错误
【发布时间】:2013-05-15 14:04:54
【问题描述】:

我有一个模块,我在其中执行项目的所有加密/解密任务。我想捕获此模块中发生的任何OpenSSL::Cipher::CipherError 异常,以便我可以处理它们。

是否可以做类似的事情

rescue_from OpenSSL::Cipher::CipherError, :with => :cipher_error

在模块内部?

【问题讨论】:

  • 您是否将该模块包含在控制器中? rescue_from 只能在控制器内部使用,因此在普通的旧 ruby​​ 对象中执行此类操作将包含一些非常肮脏的 hack。
  • 啊,明白了。谢谢@shime
  • 乐于助人。如果您想知道我所说的脏黑客是什么意思,请查看这里:simonecarletti.com/blog/2009/12/… - 我不喜欢在 Ruby 中执行此操作时的外观,并且似乎添加了不必要的混乱。在自己的方法中提取异常处理是提高代码信心的一种方法,这似乎最适合您的场景。在此处阅读更多信息:avdi.org/talks/confident-code-railsconf-2011
  • @shime 如果您愿意发表您的评论作为答案,我可以接受并关闭此问题。谢谢!

标签: ruby-on-rails ruby-on-rails-3 exception-handling rescue


【解决方案1】:

我进行了一些调查并提出了解决方案。您说您有一个模块可以在其中进行加密。我猜那个模块代表一个单例。但是,我的解决方案需要您有一个实例。

class Crypto
   def self.instance
      @__instance__ ||= new
   end
end

提取模块中的加密行为。

module Encryptable
   def encrypt
      # ...
   end

   def decrypt
      # ...
   end
end

创建一个处理异常的新模块。

module ExceptionHandler
  extend ActiveSupport::Concern

  included do
    include ActiveSupport::Rescuable
    rescue_from StandardError, :with => :known_error
  end

  def handle_known_exceptions
     yield
  rescue => ex
     rescue_with_handler(ex) || raise
  end

  def known_error(ex)
    Rails.logger.error "[ExceptionHandler] Exception #{ex.class}: #{ex.message}"
  end
end

所以现在您可以在您的Crypto 中使用新定义的handle_known_exceptions。这不是很方便,因为你没有得到太多。您仍然必须在每个方法中调用异常处理程序:

class Crypto
  include ExceptionHandler

  def print_bunnies
    handle_known_exceptions do
      File.open("bunnies")
    end
  end
end

如果我们定义一个为我们做这件事的委托者,则不需要这样做:

class CryptoDelegator
  include ExceptionHandler

  def initialize(target)
    @target = target
  end

  def method_missing(*args, &block)
    handle_known_exceptions do
      @target.send(*args, &block)
    end
  end
end

完全覆盖Crypto 的初始化,改为使用委托人。

class Crypto
  include Encryptable

  def self.new(*args, &block)
    CryptoDelegator.new(super)
  end

  def self.instance
      @__instance__ ||= new
  end
end

就是这样!

【讨论】:

  • 天哪,太棒了 - 非常感谢!我试试看!!
  • 哈哈,这让我很困扰,因为我已经问过自己几次你的问题了。玩这个对我来说非常有趣,所以我决定制作一个可以在 Rails 之外启用rescue_from 的 gem。 github.com/shime/rescue_from_ruby
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多