# Problem catching nested exception

**URL:** <https://www.ruby-forum.com/t/problem-catching-nested-exception/151903>\
**Category:** Ruby\
**Created:** [October 27, 2008, 6:35pm UTC](https://www.ruby-forum.com/t/problem-catching-nested-exception/151903 "2008-10-27T18:35:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![TJTJTJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@TJTJTJ](https://www.ruby-forum.com/u/TJTJTJ)\
**Post date:** [October 27, 2008, 6:35pm UTC](https://www.ruby-forum.com/t/problem-catching-nested-exception/151903/1 "2008-10-27T18:35:51Z")

</div>

Hello,

I’m new to ruby and just wrote a script that try to send many email,  
reading them from a database. For each domain, the script opens a TCP  
socket to the first available MX, and try to send as many email as it  
can.

My problem is that my script does not always catch exception as I  
want, and I think my exception handling in nested loops is not correct.  
Here is a code extract, starting with a SMTP connection :

```
  begin
    Timeout.timeout 1 do
      smtp = Net::SMTP.start mx, 25, $hostname
    end
  rescue Exception => e
    case e
      when Timeout::Error
        error = 'timeout connect'
      when Errno::ECONNREFUSED
        error = 'connection refused'
      when Errno::ECONNRESET
        error = 'connection reset'
      when Errno::EHOSTUNREACH
        error = 'host not reachable'
      else
        error = "unknown #{e.to_s}"
    end
    puts " KO #{error}, next MX" if $verbose
    next
  end

  domain.addr.each do |addr|
    puts " #{addr.email} (#{addr.id})" if $verbose

    begin
      Timeout.timeout 1 do
        smtp.send_message data, mailing.return_path, addr.email
      end
    rescue Exception => ee
      case ee
        when Net::SMTPServerBusy, Net::SMTPSyntaxError, 

```

Net::SMTPFatalError, Net::SMTPUnknownError  
error = ee.to\_s.strip  
when Timeout::Error  
error = ‘001 timeout send’  
when EOFError  
error = ‘002 eof’  
when Errno::ECONNRESET  
error = ‘004 connection reset’  
when TypeError  
error = ‘090 strange TypeError’  
else  
error = “unknown #{ee.to\_s}”  
end  
puts " KO #{error}" if $verbose  
next  
end

```
    puts " OK" if $verbose
  end

  smtp.finish
  break

```

“Most of the time” it works, but sometimes my script failed that  
way :

```
  email@address (693792)
    KO 451 This server employs greylisting as a means of reducing

```

spam. Please resend e-mail shortly.  
/usr/lib/ruby/1.8/net/protocol.rb:133:in `sysread': Connection reset by peer (Errno::ECONNRESET) from /usr/lib/ruby/1.8/net/protocol.rb:133:in `rbuf\_fill’  
from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout' from /usr/lib/ruby/1.8/timeout.rb:76:in `timeout’  
from /usr/lib/ruby/1.8/net/protocol.rb:132:in `rbuf_fill' from /usr/lib/ruby/1.8/net/protocol.rb:116:in `readuntil’  
from /usr/lib/ruby/1.8/net/protocol.rb:126:in `readline' from /usr/lib/ruby/1.8/net/smtp.rb:664:in `recv\_response’  
from /usr/lib/ruby/1.8/net/smtp.rb:651:in `getok' ... 8 levels... from /root/bin/mailing_3.rb:195:in `each’  
from /root/bin/mailing\_3.rb:195  
from /root/bin/mailing\_3.rb:193:in `each’  
from /root/bin/mailing\_3.rb:193

I do not understand why Errno::ECONNRESET is not catch, because I use  
it in each rescue block, and I do not see why it would be thrown in  
another part of the script. I also do not understand why “sometimes” it  
work as I want and “sometimes” not.

I removed some part of the script in this post because of its length,  
full script is available at :

[http://pastie.org/301549](http://pastie.org/301549)

Any comment will be greatly welcomed, not only for my exception  
problem, but I really need to understand that last one 😉

---

<div class="post-metadata">

**Author:** ![TJTJTJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@TJTJTJ](https://www.ruby-forum.com/u/TJTJTJ)\
**Post date:** [October 27, 2008, 10:30pm UTC](https://www.ruby-forum.com/t/problem-catching-nested-exception/151903/2 "2008-10-27T22:30:39Z")

</div>

It’s possible the exception is being raised where you do not expect it,  
e.g. in smtp.finish

Try to find out exactly what line in mailing\_3.rb generates the  
exception. The fact that it is hidden under “… 8 levels…” is  
annoying here.

I’m not sure if there’s a generic way to stop Ruby suppressing the  
intermediate levels of the exception report, but a simple solution is to  
wrap your code with:

begin  
… rest of code  
rescue Exception =\> e  
STDERR.puts “#{e.message}\n#{e.backtrace.join(”\n")}"  
end

---

<div class="post-metadata">

**Author:** ![TJTJTJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@TJTJTJ](https://www.ruby-forum.com/u/TJTJTJ)\
**Post date:** [October 28, 2008, 10:10am UTC](https://www.ruby-forum.com/t/problem-catching-nested-exception/151903/3 "2008-10-28T10:10:46Z")

</div>

On 2008-10-27, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> It’s possible the exception is being raised where you do not expect it,  
> e.g. in smtp.finish

You are right, exception was raised by smtp.finish, and I really did  
not expect it !

> Try to find out exactly what line in mailing\_3.rb generates the  
> exception. The fact that it is hidden under “… 8 levels…” is  
> annoying here.

Yes, and I should rewrite those nested loops in a clean way.

> I’m not sure if there’s a generic way to stop Ruby suppressing the  
> intermediate levels of the exception report, but a simple solution is to  
> wrap your code with:
> 
> begin  
> … rest of code  
> rescue Exception =\> e  
> STDERR.puts “#{e.message}\n#{e.backtrace.join(”\n")}"  
> end

Thank you for your time and all these informations.

---

<div class="post-metadata">

**Author:** ![TJTJTJ](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5ac83/32.png) [@TJTJTJ](https://www.ruby-forum.com/u/TJTJTJ)\
**Post date:** [June 18, 2009, 8:54am UTC](https://www.ruby-forum.com/t/problem-catching-nested-exception/151903/4 "2009-06-18T08:54:24Z")

</div>

TJ wrote:

> Hello,
> 
> I’m new to ruby and just wrote a script that try to send many email,  
> reading them from a database. For each domain, the script opens a TCP  
> socket to the first available MX, and try to send as many email as it  
> can.

please send a copy this script,thanks
