How to Rescue From An Error in Rake - ruby-on-rails

How do I rescue from a
undefined method
error in this code
for user in #users do
#customer = Stripe::Customer.retrieve(user.stripe_customer_token)
if #customer.subscription.nil?
elsif #customer.subscription.plan.id == 2
user.silver_reset
elsif #customer.subscription.plan.id == 3
user.gold_reset
end
end
I have tried a plain rescue call, but rake isn't liking it.
What is way to rescue from the error?
UPDATE:
The way I was doing it
for user in #users do
#customer = Stripe::Customer.retrieve(user.stripe_customer_token)
rescue_from Exception => exception
# Logic
end
if #customer.subscription.nil?
elsif #customer.subscription.plan.id == 2
user.silver_reset
elsif #customer.subscription.plan.id == 3
user.gold_reset
end
end
The Error
/home/user/rails_projects/assignitapp/lib/tasks/daily.rake:25: syntax error, unexpected keyword_rescue, expecting keyword_end
rescue Exception => exception
Rake 0.9.2.2
Rails 3.2.5

Use try to wrap the problem method and return nil if it doesn't exist. E.g.:
unless #customer = Stripe::Customer.try(:retrieve, user.stripe_customer_token)
# Logic
end
Alternatively, this catches more errors:
unless #customer = Stripe::Customer.retrieve(user.stripe_customer_token) rescue nil
# Logic
end
Or this is more what you were trying for:
#users.each do |user|
begin
#customer = Stripe::Customer.retrieve(user.stripe_customer_token)
rescue StandardError => error
# handle error
end
end

I still haven't enough reputation to comment, but regarding the above answer's third option: Don't rescue from Exception!
Exception is the root of Ruby's exception hierarchy, so when you rescue Exception you rescue from everything, including subclasses such as SyntaxError, LoadError, and Interrupt.
If you want to learn more, check out Why is it a bad style to `rescue Exception => e` in Ruby?

Related

rescue_from being executed twice

I am attempting to rescue RuntimeErrors from within my controller using rescue_from, log it as a HealthNotice, and then redirect the user with a flash message, but I'm finding that in certain circumstances, the rescue_from method is being run twice (I end up with 2 duplicate HealthNotices). If the exception is rasied from a function called in a method (such as the test method below), it only creates one, but if I raise the exception directly within the method (such as test2), the rescue function is running twice (although strangely I don't get a double render error -- ??)
class Portal::BluerimController < PortalController
rescue_from RuntimeError, with: :error_handler
def error_handler(e)
hn_long_message = "#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}\n\nPARAMS:\n#{params}"
HealthNotice.create(name: "API Exception Handled", severity: "WARNING", short_message: e.message, long_message: hn_long_message)
flash[:notice] = e.message
redirect_to :action => :index and return
end
def test
Sotal.new.test # a method that raises a RuntimeError -- only 1 HealthNotice
end
def test2
raise "an error" # results in duplicate HealthNotice
end
end
Any suggestions on what I'm doing wrong? Thanks!

ActiveRecord rollback and return RecordInvalid message

I want to save multiple objects, and rollback all if any of them fail. But I also want to render the ActiveRecord::RecordInvalid message so the user knows why it didn't save. How do I do this?
def save_multiple_things_or_error
ActiveRecord::Base.transaction do
thing_one.save!
thing_two.save!
rescue ActiveRecord::RecordInvalid => exception
# exception.message is what I want to render
raise ActiveRecord::Rollback
end
end
This doesn't work for a few reasons. I believe the rescue should be in a begin end block, but then if I raise the rollback, I lose the RecordInvalid exception.
you could try this one:
begin
ActiveRecord::Base.transaction do
thing_one.save!
thing_two.save!
end
rescue => e
raise ActiveRecord::Rollback
end
this works fine for my situation

RSpec having trouble stubbing method called with inline rescue

I'm trying test a method on a controller:
def a_method(list)
#users = []
list.each do |x|
if user=User.find(x) rescue nil
#users << user
end
end
end
In my Rspec example I have :
it "should do something" do
User.stub :find => 'user'
controller.a_method([1,2,3,4])
assigns[:users].should == ['user','user','user','user']
end
Problem:
it always rescues the find method user=User.find(x) rescue nil, even though I've stubbed it out.
If I remove the rescue nil it works fine.
Any ideas?
The if conditional doesn't accept a statement modifier such as rescue half way into the statement.
You can put the rescue at the end of the complete if statement as in:
if user=User.find(x)
#users << user
end rescue nil
why don't you use find_by_id instead of find?
find_by_id returns nil if the id does not exists instead of throwing the exception, it's almost the same you are doing but a little faster I guess and cleaner to read it

Is it possible to re-raise an ActiveRecord::Rollback exception from inside a transaction block?

In my rails app, I have a transaction block in a controller's create action in which I attempt to create two records.
def create
ActiveRecord::Base.transaction do
#foo = Foo.new(params[:foo].except(:bar))
raise ActiveRecord::Rollback unless #foo.save
#bar = Bar.new(params[:foo][:bar])
raise ActiveRecord::Rollback unless #bar.save
end
end
I'd like to be able to rescue from the Rollback so I can return an error indicating which save failed.
rescue ActiveRecord::Rollback => e
#foo.errors = e if #foo.errors.blank?
ensure
respond_with #foo
end
However, I never get into the rescue block. I assume this is because, as the rails documentation states, the transaction block eats the Rollback exception and doesn't re-raise it. Is there a way to force this exception to be re-raised?

How do I disable rescue handlers in Ruby on Rails apps when I'm running functional tests?

I have a number of controllers in my Ruby on Rails apps with a rescue handler at the end of the action that basically catches any unhandled errors and returns some kind of "user friendly" error. However, when I'm doing rake test I'd like to have those default rescue handlers disabled so I can see the full error & stack trace. Is there any automated way to do this?
Update to clarify: I have an action like this:
def foo
# do some stuff...
rescue
render :text => "Exception: #{$!}" # this could be any kind of custom render
end
Now when I functional test this, if the exception is raised then I'm going to get just a little bit of info about the exception, but what I'd like is for it to act as though there's no rescue handler there, so I get the full debug information.
Update: SOLUTION
I did this:
rescue:
raise unless Rails.env.production?
render :text => "Exception: #{$!}" # this could be any kind of custom render
end
Not quite automated, but how modifying your code to re-throw exceptions whenever called within a test?
Perhaps something like this:
def foo
# do some stuff...
rescue
raise if ENV["RAILS_ENV"] == "test"
render :text => "Exception: #{$!}" # this could be any kind of custom render
end
Have you looked at using the assert_raise( exception1, exception2, ... ) { block } call and then printing the exception from the block?
Which method are you using? There are two rescue methods in ActionController.
I have this in my base controller:
def rescue_action_in_public(exception)
response_code = response_code_for_rescue(exception)
status = interpret_status(response_code)
respond_to do |format|
format.html { render_optional_error_file response_code}
format.js { render :update, :status => status do |page| page.redirect_to(:url => error_page_url(status)) end}
end
end
This only displays custom errors in production mode.
I think the easiest thing to do is verify that the correct render was called-- or whatever was different from the regular, non-exceptional case.
You shouldn't need to disable your rescue block. Use the assert_raise method (as suggested by Scott), and in the block, call the method that you expect an exception from.
For example:
def test_throws_exception
assert_raise Exception do
raise_if_true(true)
end
end

Resources