task does not get 'failed' when using rescue - ruby-on-rails

I have a task like this...
def self.perform(parsed_json)
do_hard_work
use_faye_to_push_status
rescue => exception
use_faye_to_push_error
end
but, when I use the 'rescue', the task doesn't enter on the failed task list. Is there a way to, even using rescue, set the task as failed?

Rescuing from the error will stop it from proceeding any further up the call stack. With that said, you can simply raise again inside the rescue block in order to propagate it upwards:
def self.perform(parsed_json)
do_hard_work
use_faye_to_push_status
rescue => exception
use_faye_to_push_error
raise
end

Related

Execute method on exception raised without rescuing

I'm using Sidekiq, and I'd like to execute a method when an exception is raised in a background job, without rescuing the error.
Currently, I have:
begin
# job
rescue => SomeError
# run method
end
However, since it rescues the error, it does not go in the "failed" section of Sidekiq.
I'd like to execute code when an exception is raised, but without rescuing it. How can I do this ?
Just re-raise and you are all set.
begin
# job
rescue => SomeError
# run method
raise
end

Non-fatal rescue in Rails

I'm trying to run a command that might fail sometimes. When it fails, it throws an exception.
What I'd like it to do is just log the error quietly and continue executing the next line below it, rather than aborting and going into the 'rescue' block. How should I approach this?
My current code is as follows:
rescue_from 'Gibbon::MailChimpError' do |exception|
logger.error("MAILCHIMP: #{exception}")
end
When I call the Mailchimp API, sometimes there is an error, and this disrupts the flow of my application. I just want it to carry on executing as if nothing has happened, and just note there was an error in the log.
How about something like this:
def rescuing(&block)
begin
yield
rescue NameError => e
puts "(Just rescued: #{e.inspect})"
end
end
rescuing do
puts "This is dangerous"
raise NameError
end
puts "... but I'm still alive"
Obviously, you'd have to replace NameError with the exception you want to be protected against.

Stubbing an exception, but evaluating normally (RSpec)

I'm trying to update an instance variable #status on an object based on the performance of a block. This block also makes calls to another class.
def run
#entries.keep_if { |i| valid_entry?(i) }.each do |e|
begin
unique_id = get_uniqueid e
cdr_record = Cdr.find_by_uniqueid(unique_id).first
recording = cdr_record.nil? ? NullAsteriskRecording.new : AsteriskRecording.new(cdr_record, e)
recording.set_attributes
recording.import
rescue Exception => e
fail_status
end
end
end
fail_status is a private method that updates the instance variable to :failed. Through breaking some other things, I've basically verified this code works, but I want a test in place as well. Currently, I've got the following:
context "in which an exception is thrown" do
before do
#recording = double("asterisk_recording")
#recording.stub(:import).and_raise("error")
end
it "should set #status to :failed" do
# pending "Update instance variable in rescue block(s) of #run"
subject.run
subject.status.should eq :failed
end
end
But the test always fails. The rescue block is never evaluated (I checked with a puts statement that would be evaluated when I hardcoded in a raise statement). Am I using the double feature wrong, here? Or am I doing myself in by stubbing out an exception, so the rescue block never gets run?
You set up #recording in your before block, but the code you have posted for your run method will not use that #recording instance and therefore the call to recording.import in the run method will not raise an exception.
In your run method, recording can either end up being an instance of NullAsteriskRecording or AsteriskRecording. If you know that it is going to be an AsteriskRecording as your current test implies, one approach would be to change your before block to the following:
before do
AsteriskRecording.any_instance.stub(:import).and_raise("error")
end

Rails not catching exception in rescue block

User model has defined indexes to be searched using ThinkingSphinx. However when I stop my searchd deamon, I would like my method to fail gracefully and not throw an error. Normally I do this by using a rescue block for catching exceptions. But in this case, it still throws the error and the puts statement is never executed.
def search_users(key)
begin
search_results = User.search(key,options)
rescue Exception
puts "Hello World!!!"
search_results = []
end
return search_results
end
Following is the error i get:
Riddle::ConnectionError (Connection to 127.0.0.1 on 3201 failed. Connection refused - connect(2)):
Is there any way out?
Solved it.
Add the :populate => true option to your search calls.
Normally, Thinking Sphinx lazily loads search results (allowing for
sphinx scopes and such) - but if you want the rescue to take effect,
then you'll need to force the results to load immediately - hence the
:populate option.
Refer the link posted above for further reading.
Given ruby return semantics, you can compress your code:
def search_users(key)
begin
User.search(key,options)
rescue
puts "Hello World!!!"
[]
end
end
It is evil to rescue Exception. Just use rescue, which rescues StandardError, which captures most of the stuff you want it to. Otherwise you also capture SyntaxError, LoadError, SystemExit and other stuff you don't intend. In this case, rescue Riddle::ConnectionError is appropriate, but not necessary.

Rails: Returning errors from Module to Rake task?

How do I pass an error from my Module back to the rake task that called it?
My rake task looks like this:
require 'mymodule.rb'
task :queue => :environment do
OPERATOR = Mymodule::Operator.new
begin
OPERATOR.initiate_call (1234567189)
rescue StandardError => bang
puts "Shit happened: #{ bang} "
end
end
And here is my module..
module Mymodule
class Operator
def initiate_call (number)
begin
# make the call
rescue StandardError => bang
flash[:error] = "Error #{bang}"
return
end
end
end
end
I also call this module from a controller so it would be nice to have an error handling solution that is more or less agnostic.
Running Rails 3. Any unrelated comments (i.e. suggestions) on my code structure are more than welcomed :)
Your Operator#initiate_call method traps StandardError exceptions so your rake task will never see them. I'd drop the rescue from initiate_call and let the caller deal with all the exception handling. Then, you'd have flash[:error] = "Error #{bang}" in your controller's exception handler and the rake task would remain as-is.
The basic approach is to push the error handling up the call stack all the way to someone that can do something about it; initiate_call can't really do anything useful with the exception so it shouldn't try to handle it.

Resources