Consistency in 'raise'? usage

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"

and

raise ArgumentError, "unsupported address family"

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”.

Is there a convention to be observed for raising exceptions within a
module?
If there is a convention that says raise should be used consistenly
within a module, how should I pursue a remedy?

-Dennis-

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”.

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.