Best practises for exception handling

I’m write a wrapper for a web service and am wondering about the best
way to handle exceptions.

The main method in the wrapper sends either a HEAD or GET request to a
web server using Net::HTTP.

Should I catch any exceptions thrown by Net::HTTP and then throw back
my own exception, or should I leave the exceptions totally un-handled?

Alex

On Nov 8, 2007 2:04 PM, Alex D. [email protected] wrote:

I would raise a new error that’s on the same level of abstraction as
the calling code.

Pat

On Nov 8, 2007, at 3:04 PM, Alex D. wrote:

I’m write a wrapper for a web service and am wondering about the best
way to handle exceptions.

The main method in the wrapper sends either a HEAD or GET request to a
web server using Net::HTTP.

Should I catch any exceptions thrown by Net::HTTP and then throw back
my own exception, or should I leave the exceptions totally un-handled?

i generally do one of two things

a) let the exception pass through. this is ok if, and only if, there
is nothing reasonable your code could do to retry. if you do retry
you have you have a configurable numbmer of retries, of course.

b) wrap the errors. my preferred approach is something like

module Wrapper
class Error < ::StandardError
attr_accessor :exception

   def self.wrapping exception, *a, &b
     e = new *a, &b
     e.exception = exception
     e
   end
 end
 class Specific < Error; end
 class EvenMoreSpecific < Specific; end

end

this allows client code respond appropriately to specific errors or
simply to rescue the entire class of errors your wrapper might throw
and, when you want to wrap another error you can

rescue => e
raise Error.wrapping(e)
end

i would say that you have to have a good reason to pick b over a, but
they do exist.

cheers.

a @ http://codeforpeople.com/

ara.t.howard wrote:

a) let the exception pass through. this is ok if, and only if, there is
nothing reasonable your code could do to retry. if you do retry you
have you have a configurable numbmer of retries, of course.

b) wrap the errors. my preferred approach is something like

Another possibility, somewhere between a and b: rescue the exception and
re-raise, but add some more information to the message. That extra info
might be, for example, IP address and port during network operations.
This doesn’t change the structure of exception handling, since the
Exception subclass is the same and it will be handled at the same point,
eventually, but it can be very useful for logging/debugging and for
presenting an informative message to the user, if your program is
interactive.

On Nov 8, 2007, at 7:20 PM, Joel VanderWerf wrote:

Another possibility, somewhere between a and b: rescue the
exception and re-raise, but add some more information to the
message. That extra info might be, for example, IP address and port
during network operations. This doesn’t change the structure of
exception handling, since the Exception subclass is the same and it
will be handled at the same point, eventually, but it can be very
useful for logging/debugging and for presenting an informative
message to the user, if your program is interactive.

good point joel, i recently added this to main:

             rescue Exception => e
               handle_exception e
             end

 def handle_exception e
   if e.respond_to?(:error_handler_before)
     fcall(e, :error_handler_before, self)
   end

   if e.respond_to?(:error_handler_instead)
     fcall(e, :error_handler_instead, self)
   else
     if e.respond_to? :status
       exit_status(( e.status ))
     end

     if Softspoken === e or SystemExit === e
       stderr.puts e.message unless(SystemExit === e and

e.message.to_s == ‘exit’) ### avoids double message for abort(‘message’)
else
fatal{ e }
end
end

   if e.respond_to?(:error_handler_after)
     fcall(e, :error_handler_after, self)
   end

   exit_status(( exit_failure )) if exit_status == exit_success
   exit_status(( Integer(exit_status) rescue(exit_status ? 0 : 1) ))
   exit exit_status
 end

which basically allows exceptions to be extended with modules or have
methods defined on them which affect how they are handled. it seems
like a useful pattern but i’ve only just started using it.

cheers.

a @ http://codeforpeople.com/

Joel, A,

Thank you both for your responses - they made the gap in my knowledge
quite plain, so I’m off to do some more homework on exceptions.

Alex