Unable to rescue Errno::ECONNRESET during

Y

Yu-shan Fung

For some reason my rescue clause is not catching this exception. Here's
the stack trace:

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/openssl/buffering.rb:35:in
`sysread': Connection reset by peer (Errno::ECONNRESET)
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/openssl/buffering.rb:35:in
`fill_rbuff'
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/openssl/buffering.rb:106:in
`gets'
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/imap.rb:991:in
`get_response'
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/imap.rb:929:in
`receive_responses'
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/imap.rb:922:in
`initialize'
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/imap.rb:921:in
`start'
from
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/imap.rb:921:in
`initialize'
from batch/test.rb:6:in `new'
from batch/test.rb:6
from batch/test.rb:4:in `loop'
from batch/test.rb:4

This is the line in test.rb where the error occurs:
imap = Net::IMAP.new('imap.gmail.com', 993, true)


Here's my test code:

loop do
begin
imap = Net::IMAP.new('imap.gmail.com', 993, true)
imap.login('xxxxx', 'yyyyy')
imap.select('Inbox')
imap.expunge
imap.logout
$stdout.putc '.'
$stdout.flush
rescue Net::IMAP::NoResponseError => e
puts "IMAP no response"
rescue Net::IMAP::ByeResponseError => e
# send to log file, db, or email
puts "IMAP bye response"
rescue Errno::ECONNRESET => e
puts "Connection reset by peer"
puts e.backtrace
rescue Exception => e
puts "IMAP Error-#{e.class}\n#{e.message}"
puts e.backtrace
end
sleep 1
end


Either the Errno::RCONNRESET or the the Exception clause should catch
the exception, print the error and continue right? But each time it hits
the ECONNRESET error, it terminates. Any idea why?

Thanks a bunch!
 
B

Brian Candler

What's interesting is that line 929 of net/imap.rb is in the backtrace:

def receive_responses
while true
begin
resp = get_response # line 929
rescue Exception
@sock.close
@client_thread.raise($!)
break
end

It looks like the exception should be caught here, and explicitly
re-raised in another thread from line 932. You could try adding some
STDERR debugging before and after the get_response line, and inside the
rescue Exception clause.

Maybe "@sock.close" should be "@sock.close rescue nil" in case another
exception is raised then. But line 931 isn't in the backtrace.

Raising and catching the exception in another thread ought to work as
far as I can see:

class Foo
def initialize
t = Thread.current
Thread.start do
t.raise Errno::ECONNRESET
end.join
end
end

begin
f = Foo.new
rescue Errno::ECONNRESET
puts "Caught it: #{$!.backtrace.join("\n")}"
end
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top