I have the following method in one of my models to save a user record:
def save_user(params)
begin
save_user_details(params)
rescue ActiveRecord::RecordInvalid => ex
{ success: false, errors: ex.messages }
rescue Exception => ex
Rails.logger.info(ex.message)
Rails.logger.info(ex.backtrace.join(‘\n’)
{ success: false, errors: ’Some error occurred.}
end
end
We can see that the rescue
block is heavy and such block is common in other actions as well. So I gave a thought to refactor this and move the rescue
block to a separate function. I want to implement something like this:
def save_user(params)
begin
save_user_details(params) # my method to save the details
handle_the_exception # not sure how to implement this
end
def handle_the_exception
# How to handle here ?
end
Any thoughts on an implementation as in above will be a great help.
The method definition itself does the work of begin , so you can omit it. You can also do this with blocks. Now, there is one more way to use the rescue keyword without begin .
A rescue block can be what saves you from falling and injuring yourself, as they protect you from falling to the ground when working at height. The synthetic rope or cable that is wrapped around the reel of the block works like a retractable lifeline, which suspends you in the air in the event of a fall.
A raised exception can be rescued to prevent it from crashing your application once it reaches the top of the call stack. 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.
Ruby Internal try catch (raise and rescue) In case exceptions happen in the begin block it will halt and control will go between rescue and end, and we can return a valid message for the user in case of exceptions. Every time for a rescue statement Ruby checks and compares the exception raised for each parameter.
Something like this:
def save_user(params)
handle_exception do
save_user_details(params) # my method to save the details
end
end
def handle_exception(&block)
begin
block.call
rescue => ex
Rails.logger.info(ex.message)
Rails.logger.info(ex.backtrace.join("\n")
{ success: false, errors: "Some error occurred."}
end
end
In IRB:
2.2.0 :021 > def handle_exception(&block)
2.2.0 :022?> begin
2.2.0 :023 > block.call
2.2.0 :024?> rescue => ex
2.2.0 :025?> puts ex.inspect
2.2.0 :026?> puts "handled"
2.2.0 :027?> end
2.2.0 :028?> end
=> :handle_exception
2.2.0 :029 > handle_exception do
2.2.0 :030 > raise "hell"
2.2.0 :031?> puts "Don't reach me"
2.2.0 :032?> end
#<RuntimeError: hell>
handled
=> nil
You could try doing
def save_user(params)
save_user_details(params)
rescue => e
handle_exception(e)
end
def handle_exception(error)
Rails.logger.info(error.message)
Rails.logger.info(error.backtrace.join(‘\n’))
{ success: false, errors: error.messages }
end
And here's why you shouldn't rescue Exception
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