Skip to content
Jing Lu edited this page Jun 17, 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 two 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. Attempt 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 detected error in a list.

     cs = srm.Compile(@"
         var hello = function() {
             console.log('hello');    
         }                            /* error: missing ; */
    
         hello();
    
         function fun1() {
             return function() {        /* error: missing } */
         };
    
         fun1();
     ", true);
    
     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 happened. ReoScript try to complete the syntax-tree after an error happening. In the above example the script still can be executed.

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 or 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());

Display call-stack information at runtime

The full call-stack information can be displayed as below:

    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 displayed as below:

    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 result about try block, the finally block always be executed.

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'
}