Forum: IronRuby hosting: howto get the nice ruby backtrace on exception thrown from ruby?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Meinrad R. (Guest)
on 2009-02-18 01:29
(Received via mailing list)
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<RubyArray>("__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
Meinrad R. (Guest)
on 2009-02-18 11:29
(Received via mailing list)
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.
<removed_email_address@domain.invalid
Tomas M. (Guest)
on 2009-02-19 04:46
(Received via mailing list)
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<ExceptionOperations>();
            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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] 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.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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<RubyArray>("__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
Meinrad R. (Guest)
on 2009-02-19 11:06
(Received via mailing list)
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:
http://www.eqqon.com/index.php/Navigating_in_Excep...).
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. <
Tomas M. (Guest)
on 2009-02-19 19:11
(Received via mailing list)
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: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Meinrad
Recheis
Sent: Thursday, February 19, 2009 1:06 AM
To: removed_email_address@domain.invalid
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:
http://www.eqqon.com/index.php/Navigating_in_Excep...).
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.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>>
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<ExceptionOperations>();

            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:
removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>
[mailto:removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>]
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.
<removed_email_address@domain.invalid<mailto:removed_email_address@domain.invalid>> 
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<RubyArray>("__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
This topic is locked and can not be replied to.