Я немного исследовал и нашел решение. Вы сказали, что у вас есть модуль, в котором вы выполняете шифрование. Я предполагаю, что этот модуль представляет собой синглтон. Однако мое решение требует, чтобы у вас был экземпляр.
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
Вот и все!
person
shime
schedule
14.06.2013
rescue_from
предназначен для использования только внутри контроллеров, поэтому выполнение чего-то подобного внутри простых старых объектов ruby будет включать в себя несколько очень грязных хаков. - person shime   schedule 15.05.2013