ScriptingRuntimeHelpers.GetDynamicStackFrames does not work for IronRuby frames 
though, only Python is using this technique of stack tracing.

Tomas

-----Original Message-----
From: ironruby-core-boun...@rubyforge.org 
[mailto:ironruby-core-boun...@rubyforge.org] On Behalf Of Jimmy Schementi
Sent: Tuesday, December 29, 2009 3:27 AM
To: ironruby-core@rubyforge.org
Subject: Re: [Ironruby-core] Handling runtime errors in embedded applications

James,

To be up-front, your requirements are all possible with IronRuby.

For syntax errors, you're doing the right thing by using 
ScriptSource.Compile(ErrorListener).

For runtime errors, this gets trickier since all IronRuby runtime errors are 
also actual CLR exceptions, so you need to depend on the CLR's exception 
catching mechanisms to detect runtime errors and have your application react 
accordingly. While using try/catch is one way to simply capture exceptions, as 
you say, it doesn't cover all cases like catching exceptions from other 
threads. To solve this, you can hook the CLR's ApplicationUnhandedException 
event to catch all exceptions from code executing in an AppDomain:
   
   public static void Main() {
      AppDomain currentDomain = AppDomain.CurrentDomain;
      currentDomain.UnhandledException += new 
UnhandledExceptionEventHandler(MyHandler);
      try {
         throw new Exception("1");
      } catch (Exception e) {
         Console.WriteLine("Catch clause caught : " + e.Message);
      }
      throw new Exception("2");
      // Output:
      //   Catch clause caught : 1
      //   MyHandler caught : 2
   }
   static void MyHandler(object sender, UnhandledExceptionEventArgs args) {
      Exception e = (Exception) args.ExceptionObject;
      Console.WriteLine("MyHandler caught : " + e.Message);
   }

AppDomain.UnhandedException documentation: 
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx.

Now that you have a reliable way of capturing the actual exception object, you 
need to do something useful with it. Rather than using RubyExceptionData, it's 
preferred to use the DLR hosting API: 
"ScriptEngine.GetService<ExceptionOperations>()". This gives you a 
ExceptionOperations type, which you can use to format an exception as the 
language defines. 

However, it sounds like you'd rather get a list of stack frames to iterate 
through, and get information about the frame, rather than just a stacktrace 
string. You can get the actual dynamic stack frames with 
ScriptingRuntimeHelpers.GetDynamicStackFrames(exception), which will give you a 
DynamicStackFrame[] to iterate through, and pull out filenames, line numbers, 
and method names, without resorting to a regex.

Does that answer all your questions?

~Jimmy
________________________________________
From: ironruby-core-boun...@rubyforge.org [ironruby-core-boun...@rubyforge.org] 
on behalf of James Leskovar [li...@ruby-forum.com]
Sent: Saturday, December 26, 2009 3:12 AM
To: ironruby-core@rubyforge.org
Subject: [Ironruby-core] Handling runtime errors in embedded applications

Hi there,

So my application is basically a lightweight IDE for IronRuby, built in C#, 
with the idea that users should be able to quickly edit and prototype ruby 
scripts. Part of the application's requirements is to have the ability to 
handle compilation/syntax errors and runtime exceptions, as well as the ability 
to 'jump to' the source of errors.

At the moment, I'm wrapping CreateScriptSourceFromFile, Compile and Execute 
within a try/catch. Syntax errors are easily handled with a custom 
ErrorListener passed into ScriptSource.Compile. Handling runtime errors though 
are a little bit more tricky; the easiest way I've found so far involves 
RubyExceptionData.GetInstance and a linq expression to parse the backtrace with 
regexes. Not the most elegant solution, but it works.

However, one area where this method falls flat is when the error occurs in a 
thread created within the script itself; execution is now outside the 
try/catch, so I'm not able to catch the Exception object.
Futhermore, nothing seems to happen when the error does occur; nothing gets 
written to the errorstream, nor is there any indication of any error. It seems 
like the only way to handle these thread errors is to do it within the script 
using a begin-rescue block.

My question is, is there an easier way to get runtime error information other 
than RubyExceptionData? Additionally, what is the best way to handle errors 
when they occur in a thread other than the one which calls Execute()? It would 
be handy to be able to set some sort of global 'ErrorListener', or perhaps have 
the ability to pass in such an object to the call to Execute.

Kind regards,
James
--
Posted via http://www.ruby-forum.com/.
_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

Reply via email to