Problems with rescue clause

Hi Folks,
         I'm writing a script to check passwords against email accounts,
so I have written a method:

def tryIMAP (host, usessl, user, pass)

    proto = usessl ? "IMAPS" : "IMAP"
   begin
      imap = Net::IMAP.new(host, usessl ? 993 : 143, usessl)
   rescue SystemCallError
     raise "#{proto} failed"
   rescue SocketError
     raise "#{proto} failed"
   end
  begin
    imap.login( user, pass)
    imap.logout
    'success'
  rescue Net::IMAP::NoResponseError
    'failure'
  end

end

I use the method like this...

             while proto do
        begin
          case proto
          when 'IMAPS'
            status = tryIMAP(server, true, user, iD )

      proto = nil
    when 'IMAP'
            status = tryIMAP(server, false, user, iD )
      proto = nil
          when 'POP'
            status = tryPOP(server, user, iD )
            proto = nil
          else
            proto = nil
          end
    rescue 'IMAPS failed'
      proto = 'IMAP'
    rescue 'IMAP failed'
      proto = 'POP'
    rescue 'POP failed'
      servers[host][0] = 'NO'
      proto = nil
      STDERR.print "failed to connect to #{server}\n"
    end
      end # while proto
      print "logged in for #{target}\n" if status == 'success'

If I try a server which does not support IMAPS I get:
class or module required for rescue clause (TypeError)

I'm at a loss to figure out what is wrong. I've googled on the error
message but have not found anything useful.

BTW I'm new to ruby and I'd welcome criticism of the above code. If
there are better ways of doing this I'd love to know.

Cheers, Russell

···

--
Posted via http://www.ruby-forum.com/.

I would recommend doing:
raise RuntimeError, "#{proto} failed"
..instead of:
raise "#{proto} failed"

Then you can do rescue RuntimeError => e
..and e.message will contain the text of the exception. (e.g. IMAP failed)

Also, you don't really need two identical rescue clauses at the top,
for the two different kinds of error.
Personally, I would prevent try_imap from ever raising an exception,
and just return a status code. One for success, one for failure, and
one for an exception. That would greatly clean up the code that calls
it.

···

On 1/18/06, Russell Fulton <r.fulton@auckland.ac.nz> wrote:

Hi Folks,
         I'm writing a script to check passwords against email accounts,
so I have written a method:

def tryIMAP (host, usessl, user, pass)

    proto = usessl ? "IMAPS" : "IMAP"
   begin
      imap = Net::IMAP.new(host, usessl ? 993 : 143, usessl)
   rescue SystemCallError
     raise "#{proto} failed"
   rescue SocketError
     raise "#{proto} failed"
   end
  begin
    imap.login( user, pass)
    imap.logout
    'success'
  rescue Net::IMAP::NoResponseError
    'failure'
  end

end

I use the method like this...

             while proto do
              begin
                case proto
                when 'IMAPS'
                  status = tryIMAP(server, true, user, iD )

                  proto = nil
                when 'IMAP'
                  status = tryIMAP(server, false, user, iD )
                  proto = nil
                when 'POP'
                  status = tryPOP(server, user, iD )
                  proto = nil
                else
                  proto = nil
                end
                rescue 'IMAPS failed'
                  proto = 'IMAP'
                rescue 'IMAP failed'
                  proto = 'POP'
                rescue 'POP failed'
                  servers[host][0] = 'NO'
                  proto = nil
                  STDERR.print "failed to connect to #{server}\n"
                end
            end # while proto
            print "logged in for #{target}\n" if status == 'success'

If I try a server which does not support IMAPS I get:
class or module required for rescue clause (TypeError)

I'm at a loss to figure out what is wrong. I've googled on the error
message but have not found anything useful.

BTW I'm new to ruby and I'd welcome criticism of the above code. If
there are better ways of doing this I'd love to know.

Cheers, Russell

--
Posted via http://www.ruby-forum.com/\.

Thanks Wilson!

Wilson Bilkovich wrote:

I would recommend doing:
raise RuntimeError, "#{proto} failed"
..instead of:
raise "#{proto} failed"

Then you can do rescue RuntimeError => e
..and e.message will contain the text of the exception. (e.g. IMAP
failed)

I'll give it a try.

Also, you don't really need two identical rescue clauses at the top,
for the two different kinds of error.

Hmmm.... I initially had the two errors on the same rescue but I got
syntax errors

Personally, I would prevent try_imap from ever raising an exception,
and just return a status code. One for success, one for failure, and
one for an exception. That would greatly clean up the code that calls
it.

Yep, that probably would be a better way of doing it but I wanted to
play with the exceptions:) It is one feature of ruby that I am not
familiar with from the other languages that I've used.

I'll probabaly cut it out of the final version.

···

--
Posted via http://www.ruby-forum.com/\.