I have a module in which I am performing all of my encryption/decryption tasks for a project. I would like to catch any OpenSSL::Cipher::CipherError
exceptions that occur in this module so that I can handle them.
Is it possible to do something like
rescue_from OpenSSL::Cipher::CipherError, :with => :cipher_error
inside of a module?
In Ruby, we use the rescue keyword for that. When rescuing an exception in Ruby, you can specify a specific error class that should be rescued from. Note: When using raise without specifying an exception class, Ruby will default to RuntimeError .
Try and except statements are used to catch and handle exceptions in Python. Statements that can raise exceptions are kept inside the try clause and the statements that handle the exception are written inside except clause.
In a nutshell, the begin-rescue is a code block that can be used to deal with raised exceptions without interrupting program execution. In other words, you can begin to execute a block of code, and rescue any exceptions that are raised.
The try and except block in Python is used to catch and handle exceptions. Python executes code following the try statement as a “normal” part of the program. The code that follows the except statement is the program's response to any exceptions in the preceding try clause.
I've investigated a little and came with a solution. You said you have a module in which you do your encryption. I'm guessing that module represents a singleton. My solution, however, requires you have an instance instead.
class Crypto
def self.instance
@__instance__ ||= new
end
end
Extract encryption behavior in a module.
module Encryptable
def encrypt
# ...
end
def decrypt
# ...
end
end
Create a new module that handles exceptions.
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
So now you can use the newly defined handle_known_exceptions
inside your Crypto
. This is not very convenient because you haven't gained much. You still have to call the exception handler inside every method:
class Crypto
include ExceptionHandler
def print_bunnies
handle_known_exceptions do
File.open("bunnies")
end
end
end
No need to do this if we define a delegator that does that for us:
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
Completely override the initialization of Crypto
, to use the delegator instead.
class Crypto
include Encryptable
def self.new(*args, &block)
CryptoDelegator.new(super)
end
def self.instance
@__instance__ ||= new
end
end
And that's it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With