Skip to content
Jing Lu edited this page Jun 18, 2013 · 34 revisions

Any errors happened in ReoScript will be thrown as following exceptions.

ReoScriptException
    +- ReoScriptRuntimeException
        +- ReoScriptAssertionException
        +- CallStackOverflowException
    +- ReoScriptCompilingException

Error handling in .NET

Get errors from script execution

Get errors at compile-time

ReoScript support to pre-interpret a script in text and converts it into a syntax-tree in memory (like compiling). During this operation, all the syntax errors can be detected and handled.

There is three ways to get errors at compiling-time.

  1. Catch error instantly

    When the syntax-error is detected, ReoScript throws the ReoScriptCompilingException and terminates the compiling operation instantly.

     ScriptRunningMachine srm = new ScriptRunningMachine();
     	
     CompiledScript cs = null;
     try
     {
         cs = srm.Compile("console.log('a);");              // string end without '
     }
     catch (ReoScriptCompilingException ex)
     {
         MessageBox.Show(ex.Message);
     }
    

    The message displayed as below:

     syntax error at char 16 on line 1, unexpected token <EOF>
    
  2. Try to compile the entire script, get the errors from a list after compiling is finished

    By passing the second parameter as true to srm.Compile indicates that ReoScript putting any errors in a list.

     cs = srm.Compile(@"
         var hello = function() {
             console.log('hello');    
         }                              /* error: missing ; */
    
         hello();
    
         function fun1() {
             return function() {        /* error: missing } */
         };
    
         fun1();
     ", true);
    

    When the compiling is finished, enumerate over the list to get errors.

     foreach (ErrorObject e in cs.CompilingErrors)
     {
         Console.WriteLine(e.Message);
     }
    

    The errors will be printed out like:

     syntax error at char 1 on line 6, missing SEMI
     syntax error at char 0 on line 14, expect RCURLY
    

    Some errors does not effect the script execution even it detected in compile-time. ReoScript try to complete the syntax-tree after an error happening. In the above example the script still can be executed.

  3. Try to compile the entire script, and get the error instantly

    By passing the second parameter as CompilingErrorHandler anonymous function to handle the error once it happened.

     srm.Compile(script, e=>{ MessageBox.Show(e.GetFullErrorInfo()); });
    

Get Error Information

All ReoScript exceptions may contains an ErrorObject which used in both .NET and script. ErrorObject contains error information such as line number, char position in the line and call-stack information.

StringBuilder sb = new StringBuilder();

foreach (ErrorObject e in cs.CompilingErrors)
{
    sb.AppendLine(string.Format("Message     : {0}", e.Message));
    sb.AppendLine(string.Format("Char Index  : {0}", e.CharIndex));
    sb.AppendLine(string.Format("Line        : {0}", e.Line));
    sb.AppendLine();
}

Console.WriteLine(sb.ToString());

The output is:

Message     : syntax error at char 1 on line 6, missing SEMI
Char Index  : 1
Line        : 6

Message     : syntax error at char 0 on line 14, expect RCURLY
Char Index  : 0
Line        : 14

Display call-stack information at runtime

Call-stack information stored in ErrorObject only script is running. The full call-stack information can be displayed using GetAllErrorInfo() or DumpCallStack(). For example:

try
{
    srm.Run(@"
        function get_system_path(key) {
            get_env('path=' + key);       // throw exception: get_env is not defined
        }

        function get_current_instance() {
            get_system_path('startup-path');
        }

        function get_login_user() {
            get_system_path();
        }

        get_login_user();
    ");
}
catch (ReoScriptException ex)
{
    ErrorObject e = ex.ErrorObject;

    if (e != null)
    {
        Console.WriteLine(e.GetFullErrorInfo());
    }
}

The error information will be printed out with call-stack information:

Error: Function is not defined: get_env
    at get_system_path (4:2)
    at get_login_user (12:2)
    at __entry__ (15:0)

Error Handling in script

Standard ECMAScript try/catch/finally/throw are supported by ReoScript.

Catch Error

Any errors could be caught using try catch syntax:

try {
  // calling non-existent function causes a run-time error
  undefinedfunc();
} catch(e) {
  // e is instance of Error function
  alert(e.message);
}

Finally

Does not matter what is the result of try block, run the finally block anyway.

allocMemory();

try {
  // do something and error here
  undefinedfunc();
} catch(e) {
  console.log(e);
} finally {
  releaseMemory();
}

Custom Error

You may throw a customize error with message.

try {
  if (true) {
    throw new Error('error anyway');
  }
} catch(e) {
  alert(e.message)     // 'error anyway'
}

Nested Try Catch

Errors could be thrown again, or with new one instead of old.

try {
  try {
    throw 'inner error';
  } catch(e) {
    if(e == 'inner error') {
      throw 'outer error';
    }
  }
} catch(e) {
  // e is 'outer error'
}