Forum: Ruby Unable to rescue Errno::ECONNRESET during

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Yu-shan F. (Guest)
on 2008-11-14 02:46
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!
Brian C. (Guest)
on 2008-11-14 10:30
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
This topic is locked and can not be replied to.