Best practises for exception handling

A

Alex Dunae

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
 
P

Pat Maddox

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

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

Pat
 
A

ara.t.howard

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/
 
J

Joel VanderWerf

ara.t.howard said:
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.
 
A

ara.t.howard

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/
 
A

Alex Dunae

Note: parts of this message were removed by the gateway to make it a legal Usenet post.

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
 

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,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top