Ajay
Ajay

Reputation: 4251

How to move a rescue block to a method

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.

Upvotes: 8

Views: 4722

Answers (2)

A Fader Darkly
A Fader Darkly

Reputation: 3636

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 

Upvotes: 25

Piotr Kruczek
Piotr Kruczek

Reputation: 2390

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

Upvotes: 3

Related Questions