[Ironruby-core] Raising Exceptions

John Lam (DLR) jflam at microsoft.com
Thu Dec 6 12:27:38 EST 2007

Our automatic exception mapping mechanism maps ArgumentOutOfRangeExceptions to RangeErrors. Since the correct behavior in this case appears to be raising an ArgumentError, it makes sense to catch and rethrow.

I'm attaching a PDF that shows how we map CLR exceptions to Ruby exceptions.


From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Peter Bacon Darwin
Sent: Thursday, December 06, 2007 2:40 AM
To: ironruby-core at rubyforge.org
Subject: [Ironruby-core] Raising Exceptions

Just a quick question about raising exceptions in IronRuby libraries.  Should we just simply throw a new CLR exception or do we need to use the ExceptionOps stuff when creating exceptions.
As an example, in FloatOps, I have a method for divmod:

        public static RubyArray DivMod(double self, double other) {
            // Unlike modulo, divmod throws an error if the quotient is not a proper number.
            // This appears to be an inconsistency in MRI.
            double quotient = self / other;
            if (Double.IsNaN(quotient) || Double.IsInfinity(quotient) ) {
                throw new FloatDomainError("NaN");
            return InternalDivMod(self, other);

If the quotient is not valid then we raise a FloatDomainError.  The FloatDomainError class uses ExceptionOps.MakeMessage and also ExceptionOps.InitializeException in the constructor.  A quick look at InitializeException puts some data into the Exception.Data property, which I am assuming, without going any deeper, is required by the Ruby runtime to handle the exception correctly.

This is all well and good, but when you look at BignumOps, I have a method for to_s:

        public static object ToString(BigInteger self, uint radix) {
            try {
                // TODO: Can we do the ToLower in BigInteger?
                return new MutableString(self.ToString(radix).ToLower());
            } catch (ArgumentOutOfRangeException x) {
                throw ArgumentErrorOps.Factory(new MutableString(x.Message));

Now this one needs to raise an ArgumentError, which is actually a Ruby wrapper around System.ArgumentException (i.e. ArgumentError is a pure Ruby class that "extends" the CLR class System.ArgumentException.  Now I could have just created a new ArgumentException here but since this doesn't call, apart from anything else, ExceptionOps.InitializeException, I felt I needed to use the ArgumentErrorOps.Factory method to create the exception.  I believe the primary reason for this method is so that the DLR can create exceptions from pure Ruby code, i.e. raise ArgumentError, ...

Am I being over-cautious here and should I be happily creating CLR exceptions directly and not worrying too much?  I expect and hope that this is the case, as otherwise how would the DLR deal with cases where pure .NET classes throw pure CLR exceptions?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071206/5784c170/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ExceptionHierarchy.pdf
Type: application/pdf
Size: 10274 bytes
Desc: ExceptionHierarchy.pdf
Url : http://rubyforge.org/pipermail/ironruby-core/attachments/20071206/5784c170/attachment-0001.pdf 

More information about the Ironruby-core mailing list