Ruby style question from a newby: exceptions

R

rj-cole

Hi,

Any hints on the best way to catch exceptions from the point of view of
good style for the following?

---
puts "Create connection..."
imap = IMAP.new('sslmail.somewhere.com', 993, true)
puts "Capabilities: cap = #{imap.capability().join(" ")}"
puts "Authenticate..."
logged_in = false

begin
imap.authenticate('CRAM-MD5', 'myname', 'secret')
logged_in = true
rescue Net::IMAP::NoResponseError => e
puts " Failed, #{e}"
end

puts "Try Login..."
if ! logged_in then
begin
imap.login('myname', 'secret')
logged_in = true
rescue
puts " Failed, #{e}"
end
end
---

What am I trying to do and what don't I like? Basically I want to try a
sequence of things until one of them works --- first I want to use the
authenticate method and if that fails to use the login method. Each of
these methods indicates failure by raising an exception. I want to log
each failure (because I'm experimenting with the library at this
stage). In this example I want to log each failure and on failure I
want to cacade to an alternative strategy.

How could this code be better written so that it is easier to read and
understand the flow of the code? Would it be possible to achieve
something like the following?

---
exceptions = until_success \
{ imap.authenticate ... },
{ imap.login ... }

if exceptions.failed then
puts "Unable to login: #{exceptions.join('\n')}"
else
puts "Login successfull. Record of unsuccessfull attempts: \n \
#{exceptions.join("\n ")}"
end
---

with a function until_success taking a sequence of blocks as arguments?

regards,

Richard.
 
Y

YANAGAWA Kazuhisa

Is the following irb session informative?

irb(main):013:0> c = 0
irb(main):014:0> begin
irb(main):015:1* p c
irb(main):016:1> raise
irb(main):017:1> rescue
irb(main):018:1> c += 1
irb(main):019:1> retry if c < 5
irb(main):020:1> end
1
2
3
4
=> nil
 
D

daz

YANAGAWA said:
irb(main):019:1> retry if c < 5


Hi Richard,

Here's a variation on that theme:

#--------------------------------------------------------

METHOD_Q = [ [:aaa, TypeError],
[:bbb, NoMethodError],
[:ccc, ArgumentError],
[:ddd, NameError],
].freeze

def log(item); puts "LOG: #{item}"; end

def aaa; 11 + 'Two Two'; end
def bbb; 12.sort; end
def ccc; [].each(13) {}; end
def ddd
puts "4th attempt"
# NOCONST # <--- uncomment
end


catch:)done) do
stack = METHOD_Q.dup
begin
meth, exc = stack.shift
unless meth
log "Tried everything :("
throw:)done)
end
send(meth)
log "Success at last!"
rescue exc => e
log "#{meth} error"
log "^ #{e.message}"
retry
end
end

=begin

LOG: aaa error
LOG: ^ String can't be coerced into Fixnum
LOG: bbb error
LOG: ^ undefined method `sort' for 12:Fixnum
LOG: ccc error
LOG: ^ wrong number of arguments (1 for 0)
4th attempt
LOG: Success at last!

=end
#--------------------------------------------------------


daz
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top