Forum: IronRuby Throwing Exceptions defined in Ruby from C#

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
1c29f9b1bf5f1b88ed8b0c9a9be39788?d=identicon&s=25 Daniele Alessandri (Guest)
on 2009-02-12 15:31
(Received via mailing list)

I'm refactoring and polishing the source code of my port of json/ext
to IronRuby (it's feature complete by now) but I'm wondering if there
is a better way to throw an Exception defined in ruby from C# compared
to the only solution I've came up with so far. Here is the code I'm
using right now, stripped down of checks and condensed in one method
just for the sake of brevity:

----- ruby -----

module JSON
    class JSONError < StandardError; end
    class ParserError < JSONError; end

----- C# -----

public static void RaiseParserError(RubyScope scope, String msg) {
    RubyModule eParserError;

        out eParserError

    RubyClass exceptionClass = eParserError as RubyClass;
    Type underlyingType = exceptionClass.GetUnderlyingSystemType();

    BindingFlags bindingFlags = BindingFlags.NonPublic |
                                BindingFlags.Public |

    ConstructorInfo constructor = underlyingType.GetConstructor(
        new[] { typeof(RubyClass), typeof(String) },

    Exception exceptionInstance = constructor.Invoke(
        new object[] { exceptionClass, msg }
    ) as Exception;

    throw exceptionInstance;
Cb51033949ffccd982ae32c9f890f25a?d=identicon&s=25 Tomas Matousek (Guest)
on 2009-02-13 04:33
(Received via mailing list)
Why don't you declare the exceptions in C#? I assume the library is
primarily to be used from Ruby code, not from C#, right?

1c29f9b1bf5f1b88ed8b0c9a9be39788?d=identicon&s=25 Daniele Alessandri (Guest)
on 2009-02-13 08:59
(Received via mailing list)
Yes it is meant to be used primarily from ruby as it is a port of a
rather widespread library, and a dependency for a bunch of other
libraries (see

The reason is simply to maintain compatibility with the ruby bits of
the original json library in which exceptions are defined inside a
common.rb file: this is due to the fact that this lib comes in two
flavours, json-pure (everything is ruby) and json-ext (the generator
and parser are implemented in C, the rest is ruby), so there are parts
of the code that are shared between the two and eventually invoked
from within the native code.

Anyway I'm curious, I haven't found other means to do that in a much
cleaner way :)

On Fri, Feb 13, 2009 at 04:33, Tomas Matousek
Aea6cfe04952626ab630bde47ff82f89?d=identicon&s=25 Shri Borde (Guest)
on 2009-02-13 18:56
(Received via mailing list)
I don't think your code below will work as multiple Ruby types share the
same underlying CLR type. If you want to do things in a strongly-bound
way, you would need to use the RubyUtils and other runtime helpers to
find the method "new", invoke it, etc. instead of using

An alternative is to just do an eval. Something like:
   RubyUtils.Evaluate("raise JSONError", scope)
Cb51033949ffccd982ae32c9f890f25a?d=identicon&s=25 Tomas Matousek (Guest)
on 2009-02-13 19:45
(Received via mailing list)
You can use KernelOps.RaiseException:

public static void RaiseException(RespondToStorage/*!*/
respondToStorage, UnaryOpStorage/*!*/ storage0, BinaryOpStorage/*!*/
            RubyContext/*!*/ context, object self, object/*!*/ obj,
[Optional]object arg, [Optional]RubyArray backtrace) {

You'll need to allocate local site storages to do so. The storages are
allocated automatically for methods called from Ruby.
I assume you have some entry point to the C# part of the parser that you
call from Ruby. That method should declare the storages and pass them
thru to the place where you want to raise the exception.

It might be easier to change your C# implementation not to throw Ruby
exceptions. You can throw a C# exception, catch it in Ruby and rethrow
the corresponding Ruby exception. This way your C# code would be usable
from C# apps as well, not only from Ruby code.

9d5a4bd314818560d935f2c1a4f0d2f2?d=identicon&s=25 Pete Bacon Darwin (Guest)
on 2009-02-13 20:01
(Received via mailing list)
Could you not achieve the wanted effect through a kind of monkey
I.E. Create the exception class in C# then redeclare it in the
The new class in Ruby would extend the one created in C# but wouldn't
anything if the C# one was there in the first place.  If it was there,
you were using the pure Ruby version, then it would just be creating it
the first time.  No harm done.
Off the top of my head, I haven't thought hard about this or tried it...
There are probably issues of order declaration or something.
Aea6cfe04952626ab630bde47ff82f89?d=identicon&s=25 Shri Borde (Guest)
on 2009-02-13 20:26
(Received via mailing list)
Yes, the approach of throwing a C# exception and converting it to a Ruby
exception is ideal as it preserves good layering and allows more code
reuse (since the C# code could be used by IronPython, C#, VB.Net, etc).
1c29f9b1bf5f1b88ed8b0c9a9be39788?d=identicon&s=25 Daniele Alessandri (Guest)
on 2009-02-13 21:49
(Received via mailing list)
Yeah, I don't really like my solution exactly because it is dependent
on the underlying type.
By the way I already tried to call JSON::ParserError#new from C# to
get an instance of the class and it actually worked, but then the
exception was getting thrown with an empty stack trace (well I can
guess the reason for that and it is not something unexpected).
1c29f9b1bf5f1b88ed8b0c9a9be39788?d=identicon&s=25 Daniele Alessandri (Guest)
on 2009-02-13 21:56
(Received via mailing list)
I will try going with this solution, thanks.

As for the reusability of the code from other applications/languages,
I think it would be something impossibile to begin with as the library
is tightly coupled with ruby (especially the generator class, it
interacts a lot with ruby code) and this is due to an intrinsic factor
of its conceptual design (which goes back to the original
implementation) and IMHO it is not really a matter of bad design

On Fri, Feb 13, 2009 at 19:34, Tomas Matousek
1c29f9b1bf5f1b88ed8b0c9a9be39788?d=identicon&s=25 Daniele Alessandri (Guest)
on 2009-02-13 21:57
(Received via mailing list)
I might try that just out of curiosity to see how it behaves, even
though (honestly) I don't find it too much of a clean solution.

On Fri, Feb 13, 2009 at 19:57, Pete Bacon Darwin
This topic is locked and can not be replied to.