-
Notifications
You must be signed in to change notification settings - Fork 35
Error Handling
Any errors happened in ReoScript will be thrown as following exceptions.
ReoScriptException
+- ReoScriptRuntimeException
+- ReoScriptAssertionException
+- CallStackOverflowException
+- ReoScriptCompilingException
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.
-
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);
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 happened. ReoScript try to complete the syntax-tree after an error happening. In the above example the script still can be executed.
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
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 call-stack information will also 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)
Standard ECMAScript try/catch/finally/throw are supported by ReoScript.
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);
}
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();
}
You may throw a customize error with message.
try {
if (true) {
throw new Error('error anyway');
}
} catch(e) {
alert(e.message) // 'error anyway'
}
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'
}