Hosting: howto get the nice ruby backtrace on exception thrown from ruby?

hello,

I am now currently using this ugly hack to get a reasonable (let’s say
user
friendly) exception backtrace from an error in executed code:

    public object Execute(string code, ScriptScope scope)
    {
        code = @"begin

_=(
“+code+@”
)
rescue Exception
self.message=$!.message.to_clr_string
self.backtrace = $!.backtrace
throw
end";
object result = null;
try
{
LogManager.GetLogger(“Ruby”).Debug("\r\n" + code);
result = m_engine.Execute(code, scope);

        }
        catch (Exception e)
        {
            var backtrace =

scope.GetVariable(“backtrace”);
string msg = scope.GetVariable(“message”)
+"\r\n" + string.Join("\r\n", backtrace.Select(s =>
s.ToString()).ToArray());

            LogManager.GetLogger("Ruby").Error(msg);
        }
        return result;
    }

Even though it seems to work well I am absolutely not satisfied with it.
Is
there a better way to do this?
– henon

I’ve given it some thought. I would like to avoid wrapping the code in
“begin - rescue” and instead catch the exception in c#. Then just send
the
ruby methods “message” and “backtrace” to the Ruby-exception-object from
C#.
How would that be done?
Any other hints?-- Henon

On Tue, Feb 17, 2009 at 11:36 PM, Meinrad R.
<[email protected]

You can use ExceptionService:

    var engine = Ruby.CreateEngine();
    try {
        engine.Execute(@"

def foo
goo
end

def goo
raise ‘hello’
end

foo
");
} catch (Exception e) {
var exceptionService =
engine.GetService();
string message, typeName;
exceptionService.GetExceptionMessage(e, out message, out
typeName);
Console.WriteLine(message);
Console.WriteLine(typeName);
Console.WriteLine(exceptionService.FormatException(e));
}

The current implementation is not ideal. If you’re missing some features
on the service let us know. We might consider adding them.

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Meinrad
Recheis
Sent: Wednesday, February 18, 2009 1:25 AM
To: ironruby-core
Subject: Re: [Ironruby-core] hosting: howto get the nice ruby backtrace
on exception thrown from ruby?

I’ve given it some thought. I would like to avoid wrapping the code in
“begin - rescue” and instead catch the exception in c#. Then just send
the ruby methods “message” and “backtrace” to the Ruby-exception-object
from C#. How would that be done?
Any other hints?
– Henon
On Tue, Feb 17, 2009 at 11:36 PM, Meinrad R.
<[email protected]mailto:[email protected]> wrote:
hello,

I am now currently using this ugly hack to get a reasonable (let’s say
user friendly) exception backtrace from an error in executed code:
public object Execute(string code, ScriptScope scope)
{
code = @“begin
_=(
“+code+@”
)
rescue Exception
self.message=$!.message.to_clr_string
self.backtrace = $!.backtrace
throw
end”;
object result = null;
try
{
LogManager.GetLogger(“Ruby”).Debug(“\r\n” + code);
result = m_engine.Execute(code, scope);

        }
        catch (Exception e)
        {
            var backtrace = 

scope.GetVariable(“backtrace”);
string msg = scope.GetVariable(“message”)
+“\r\n” + string.Join(“\r\n”, backtrace.Select(s =>
s.ToString()).ToArray());

            LogManager.GetLogger("Ruby").Error(msg);
        }
        return result;
    }

Even though it seems to work well I am absolutely not satisfied with it.
Is there a better way to do this?
– henon

Thanks Thomas, thats very good. As for a suggestion about
ExceptionService
features: It would be quite useful to retrieve the exception backtrace
as
string[] in order to be able format it to one’s needs. For instance, I
like
using the VisualStudio error parser to be able to jump from the
backtrace in
the output right into the right line in the source file (see my blog
post:
Navigating in Exception Stack Traces in Visual C-Sharp - eqqon).
To do that, currently, I would need to parse the formatted backtrace and
re-format it. No big deal. Just would be nice to have.

Cheers,
– henon

On Thu, Feb 19, 2009 at 3:30 AM, Tomas M. <

I completely agree with that. I think we should add a method
GetStackTrace() that returns an instance of some StackTrace class, which
is an array of StackFrames, where StackFrame is some struct/class that
contains method name, file name and line number.

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Meinrad
Recheis
Sent: Thursday, February 19, 2009 1:06 AM
To: [email protected]
Subject: Re: [Ironruby-core] hosting: howto get the nice ruby backtrace
on exception thrown from ruby?

Thanks Thomas, thats very good. As for a suggestion about
ExceptionService features: It would be quite useful to retrieve the
exception backtrace as string[] in order to be able format it to one’s
needs. For instance, I like using the VisualStudio error parser to be
able to jump from the backtrace in the output right into the right line
in the source file (see my blog post:
Navigating in Exception Stack Traces in Visual C-Sharp - eqqon).
To do that, currently, I would need to parse the formatted backtrace and
re-format it. No big deal. Just would be nice to have.

Cheers,
– henon

On Thu, Feb 19, 2009 at 3:30 AM, Tomas M.
<[email protected]mailto:[email protected]>
wrote:

You can use ExceptionService:

    var engine = Ruby.CreateEngine();

    try {

        engine.Execute(@"

def foo

goo

end

def goo

raise ‘hello’

end

foo

");

    } catch (Exception e) {

        var exceptionService = 

engine.GetService();

        string message, typeName;

        exceptionService.GetExceptionMessage(e, out message, out 

typeName);

        Console.WriteLine(message);

        Console.WriteLine(typeName);

        Console.WriteLine(exceptionService.FormatException(e));

    }

The current implementation is not ideal. If you’re missing some features
on the service let us know. We might consider adding them.

Tomas

From:
[email protected]mailto:[email protected]
[mailto:[email protected]mailto:[email protected]]
On Behalf Of Meinrad R.
Sent: Wednesday, February 18, 2009 1:25 AM
To: ironruby-core
Subject: Re: [Ironruby-core] hosting: howto get the nice ruby backtrace
on exception thrown from ruby?

I’ve given it some thought. I would like to avoid wrapping the code in
“begin - rescue” and instead catch the exception in c#. Then just send
the ruby methods “message” and “backtrace” to the Ruby-exception-object
from C#. How would that be done?
Any other hints?

– Henon

On Tue, Feb 17, 2009 at 11:36 PM, Meinrad R.
<[email protected]mailto:[email protected]> wrote:

hello,

I am now currently using this ugly hack to get a reasonable (let’s say
user friendly) exception backtrace from an error in executed code:

    public object Execute(string code, ScriptScope scope)

    {

        code = @"begin

_=(

“+code+@”

)

rescue Exception

self.message=$!.message.to_clr_string

self.backtrace = $!.backtrace

throw

end";

        object result = null;

        try

        {

            LogManager.GetLogger("Ruby").Debug("\r\n" + code);

            result = m_engine.Execute(code, scope);



        }

        catch (Exception e)

        {

            var backtrace = 

scope.GetVariable(“backtrace”);

            string msg = scope.GetVariable<string>("__message__") 

+“\r\n” + string.Join(“\r\n”, backtrace.Select(s =>
s.ToString()).ToArray());

            LogManager.GetLogger("Ruby").Error(msg);

        }

        return result;

    }

Even though it seems to work well I am absolutely not satisfied with it.
Is there a better way to do this?
– henon