Question

I have the following code:

  rescue Timeout::Error, StandardError => e
      puts "Caught exception: #{e.message}".red
      log.puts("#{e.backtrace}")
      email_ids_all.each do |email_delete|
        call= "/api/v2/emails/#{email_delete}/"
        ......

Before this rescue piece I have defined log and email_ids_all. However, neither of these are recognized within the ruby script. If i do this:

 rescue Timeout::Error, StandardError => e
    File.open(rescuelogfile, 'w') do |log| #setup log to write response codes.
      puts "Caught exception: #{e.message}".red
      log.puts("#{e.backtrace}")
      email_ids_all.each do |email_delete|
        call= "/api/v2/emails/#{email_delete}/"
        ....

log works fine, which makes sense. It would take a lot of writing to redefine the email_ids_all array and other variables contained inside my rescue block.

Is there anyway to allow variables to be recognized inside the rescue? Basically my code is laid out like this:

begin

#some code

rescue
  #above code

end

I am using ruby 1.9.3.

EDIT----

log starts right after my begin statement :

begin
  File.open(logfile, 'w') do |log| #setup log to write response codes.

log.puts works throughout the entire code except when an error is thrown, and then it runs the rescue script where log is not available.

The same goes for email_ids_all. There is an API call that generates about 10,000 emails and each of them is added to the array email_ids_all. The script is receiving an error about halfway through generating these emails, and so I need the rescue script to delete all email ids in the email_ids_all array. But for whatever reason, I get the following error:

FS_Test_Env.rb:762:in `block in <main>': undefined local variable or method `email_ids_all' for main:Object (NameError)
    from FS_Test_Env.rb:759:in `open'
    from FS_Test_Env.rb:759:in `rescue in <main>'
    from FS_Test_Env.rb:7:in `<main>'

Any thoughts?

Was it helpful?

Solution 2

The scope of the block parameter log is limited to that block. This is the whole point of the open with block.

Maybe you want to do:

begin
  log = File.open('logfile', 'w')
  ...
rescue
  ...
ensure
  log.close
end

Note that this does not cover errors when opening the logfile.

Regarding email_ids_all, I guess (!) you have the exception in a statement like:

email_ids_all = ... a long and complex calculation which raises an exception

If yes, the problem is that the assignment happens only after the whole right-hand side is calculated. The var email_ids_all is not yet created when the exception happens.

In order to access the elements created before the exception, you have to keep track of them, e.g.

begin
  email_ids = []
  10000.times do 
    email_ids << ... # create element eventually raising an exception
  end
rescue
  ... # treat the already created elements
end

OTHER TIPS

The way you put it, it should work, for example:

irb(main):001:0> begin
irb(main):002:1* x = 1
irb(main):003:1> x / 0
irb(main):004:1> rescue Exception => e
irb(main):005:1> p x
irb(main):006:1> end
1
=> 1

So it looks like the exception is thrown before your variables are defined.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top