我有一个模块,我在其中执行项目的所有加密/解密任务。我想捕获此模块中出现的任何OpenSSL::Cipher::CipherError
异常,以便我可以处理它们。
是否可以执行类似
的操作rescue_from OpenSSL::Cipher::CipherError, :with => :cipher_error
在模块内部?
答案 0 :(得分:8)
我已经调查了一下,并提出了一个解决方案。你说你有一个模块,你可以在其中进行加密。我猜这个模块代表一个单身人士。但是,我的解决方案要求您拥有一个实例。
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
现在,您可以在handle_known_exceptions
内使用新定义的Crypto
。这不是很方便,因为你没有获得太多。您仍然需要在每个方法中调用异常处理程序:
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
就是这样!