[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Best practises for exception handling

Alex Dunae

11/8/2007 10:05:00 PM

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


5 Answers

Pat Maddox

11/8/2007 10:20:00 PM

0

On Nov 8, 2007 2:04 PM, Alex Dunae <alex@dunae.ca> 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?
>
> Alex
>
>
>

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

Pat

ara.t.howard

11/9/2007 2:01:00 AM

0


On Nov 8, 2007, at 3:04 PM, Alex Dunae 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://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Joel VanderWerf

11/9/2007 2:20:00 AM

0

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.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

ara.t.howard

11/9/2007 3:43:00 AM

0


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://codeforp...
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama



Alex Dunae

11/9/2007 4:28:00 AM

0

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

ara.t.howard wrote:
>
> 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://codeforp...
> --
> share your knowledge. it's a way to achieve immortality.
> h.h. the 14th dalai lama
>
>
>
>