Exception Handling in Blocks

B

Bryan Richardson

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 https://gist.github.com/776547 the error raised does NOT get
rescued.

Please help!
 
I

Iñaki Baz Castillo

2011/1/12 Bryan Richardson said:
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 https://gist.github.com/776547 the error raised does NOT get
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 =3D 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 =3D> 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
----------------------------------------------


--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 
I

Iñaki Baz Castillo

2011/1/12 I=C3=B1aki Baz Castillo said:
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 =3D> 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).

--=20
I=C3=B1aki Baz Castillo
<[email protected]>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,113
Latest member
KetoBurn
Top