Exception Handling in Blocks

Hello All,

I’m using the Memcache protocol class in EventMachine to make calls into
a memcache server. The way the Memcache protocol class works is the user
calls the ‘get’ function with the key they want a value for and provide
a block to which the value for that key is passed. The Memcache protocol
object then registers a callback with EventMachine, in which the value
returned from memcache is then yielded to the user’s callback.

So here’s my question… if in the block I pass to the Memcache protocol
object I raise an error, how does the error get handled? In the code
example at 776547’s gists · GitHub the error raised does NOT get
rescued.

Please help!


Thanks!
Bryan

2011/1/12 Bryan R. [email protected]:

rescued.
Note that, even if you see the code as “sequential” it is not as
EventMachine works on iterations. So when you call memcache.get(:foo)
most probably a deferable object is created so the callback function
is called in a later iteration of EventMachine, so the begin-rescue
code has already been bypassed.

Test the following:


require ‘rubygems’
require ‘eventmachine’

EM.run do
memcache = EM::Protocols::Memcache.connect(‘127.0.0.1’, 11211)

begin
memcache.get(:foo) do |value|
if value.nil?
raise Exception, “Tag :foo not found”
end

  puts "Value Returned: #{value}"

  EM.stop_event_loop
end

rescue Exception => ex
puts ‘Failed to get tag…’
exit
end

puts “This shouldn’t be printed as the above code will raise, but
this does appear because memcache.get(:foo) returns inmediately and
its result is processed in a later iteration of the EM reactor”

end

2011/1/12 Iñaki Baz C. [email protected]:

Note that, even if you see the code as “sequential” it is not as
EventMachine works on iterations. So when you call memcache.get(:foo)
most probably a deferable object is created so the callback function
is called in a later iteration of EventMachine, so the begin-rescue
code has already been bypassed.

Let me explain better:

Your raised exception:
Exception, “Tag :foo not found”
is executed in a later iteration of the EM reactor so it cannot be
captured by “rescue Exception => ex”. This is, memcache.get(:foo)
returned ok so the rescue doesn’t take place. In a later EM iteration
your exception is raised but then there is no rescue to capture it.

Basically IMHO you shouldn’t raise an exception within the block
passed to memcache.get, and instead react on the same block (call
there “puts ‘Failed to get tag…’” and so on).

Got it. Thanks for the explanation Inaki!