# Best practises for exception handling

**URL:** <https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656>\
**Category:** Ruby\
**Created:** [November 8, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656 "2007-11-08T23:12:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![alexd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/96bed5/32.png) [@alexd](https://www.ruby-forum.com/u/alexd)\
**Post date:** [November 8, 2007, 11:12pm UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656/1 "2007-11-08T23:12:15Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![alexd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/96bed5/32.png) [@alexd](https://www.ruby-forum.com/u/alexd)\
**Post date:** [November 8, 2007, 11:21pm UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656/2 "2007-11-08T23:21:40Z")

</div>

On Nov 8, 2007 2:04 PM, Alex D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

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

Pat

---

<div class="post-metadata">

**Author:** ![alexd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/96bed5/32.png) [@alexd](https://www.ruby-forum.com/u/alexd)\
**Post date:** [November 9, 2007, 3:05am UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656/3 "2007-11-09T03:05:28Z")

</div>

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/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![alexd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/96bed5/32.png) [@alexd](https://www.ruby-forum.com/u/alexd)\
**Post date:** [November 9, 2007, 3:21am UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656/4 "2007-11-09T03:21:56Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![alexd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/96bed5/32.png) [@alexd](https://www.ruby-forum.com/u/alexd)\
**Post date:** [November 9, 2007, 4:44am UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656/5 "2007-11-09T04:44:24Z")

</div>

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/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![alexd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/96bed5/32.png) [@alexd](https://www.ruby-forum.com/u/alexd)\
**Post date:** [November 9, 2007, 5:29am UTC](https://www.ruby-forum.com/t/best-practises-for-exception-handling/119656/6 "2007-11-09T05:29:59Z")

</div>

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
