On Fri, May 11, 2007 at 02:32:24AM +0900, Dennis Mccracken wrote:
> Hi,
> 
> First let me say I'm new to ruby and RoR.  I am attempting to use IPAddr
> from the library in an RoR application.  Two types of raise are used in
> ipaddr.rb.
> 
>     raise "unsupported address family"

This is equivalent to

      raise RuntimeError, "unsupported address family"

> 
> and
> 
>     raise ArgumentError, "unsupported address family"

I'd agree that ipaddr is being inconsistent here.

> In writing the unit tests for my module I pass badly formed IP Addresses
> to make sure my model catches the errors.  Depending on the error I
> introduce, I need to catch the exception differently (I'm still working
> out how best to handle this).  My goals are to a) not have my
> application terminate because of an unhandled exception and b) to
> provide some guidance to the user beyond your basic "bad parameter".

http://www.zenspider.com/Languages/Ruby/QuickRef.html#34

You can always assert_raises(Exception) which will catch everything, or
assert_raises(StandardError) which will catch both RuntimeError and
ArgumentError.

However that's not a good idea for unit tests, because you'll also catch a
NoMethodError (which most likely indicates that a bug has been found in the
underlying code). However you could do something like this:

   e = assert_raises(StandardError) { ... }
   assert_equal "unsupported address family", e.message

> Is there a convention to be observed for raising exceptions within a
> module?

Some modules define their own exception hierarchies, for example

class FooException < RuntimeError; end
class FooDataError < FooException; end
class FooConnectionError < FooException; end  # etc

This is so that clients of the module can rescue FooException to catch all
errors from this module, or rescue particular subclasses if they want.

Another option, if it makes sense to do so, is to raise existing Ruby
exceptions like ArgumentError, IOError or TypeError.
It looks like this is what ipaddr is trying to do, but you found an
exception (NPI) to the rule.

Or, you could just make every exception from your module a RuntimeError, if
you don't expect your clients to be likely to want to filter out certain
types of exceptions.

B.