Skip to content

Commit

Permalink
Don't fail deferrables when callbacks raise exceptions
Browse files Browse the repository at this point in the history
* Only fail the deferrable if the exception came from the client.
  • Loading branch information
thoughtless committed Mar 15, 2012
1 parent d81ba95 commit 75ef9e6
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
5 changes: 3 additions & 2 deletions lib/mysql2/em.rb
Expand Up @@ -15,10 +15,11 @@ def initialize(client, deferable)
def notify_readable
detach
begin
@deferable.succeed(@client.async_result)
result = @client.async_result
rescue Exception => e
@deferable.fail(e)
end
@deferable.succeed(result)
end
end

Expand All @@ -34,4 +35,4 @@ def query(sql, opts={})
end
end
end
end
end
37 changes: 37 additions & 0 deletions spec/em/em_spec.rb
Expand Up @@ -44,6 +44,43 @@
results[0].keys.should include("first_query")
results[1].keys.should include("second_query")
end

it "should not swallow exceptions raised in callbacks" do
lambda {
EM.run do
client = Mysql2::EM::Client.new
defer = client.query "SELECT sleep(0.1) as first_query"
defer.callback do |result|
raise 'some error'
end
defer.errback do |err|
# This _shouldn't_ be run, but it needed to prevent the specs from
# freezing if this test fails.
EM.stop_event_loop
end
end
}.should raise_error
end

it "should swallow exceptions raised in by the client" do
errors = []
error = StandardError.new('some error')
EM.run do
client = Mysql2::EM::Client.new
defer = client.query "SELECT sleep(0.1) as first_query"
client.stub(:async_result).and_raise(error)
defer.callback do |result|
# This _shouldn't_ be run, but it needed to prevent the specs from
# freezing if this test fails.
EM.stop_event_loop
end
defer.errback do |err|
errors << err
EM.stop_event_loop
end
end
errors.should == [error]
end
end
rescue LoadError
puts "EventMachine not installed, skipping the specs that use it"
Expand Down

0 comments on commit 75ef9e6

Please sign in to comment.