problem catching nested exception

T

TJ

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

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

Brian Candler

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
 
T

TJ

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.
 
B

Big Bet

TJ said:
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
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top