Jint: please add ability to get a stacktrace from errors and exceptions

Created on 12 Nov 2014  ·  3Comments  ·  Source: sebastienros/jint

I'm building an engine that uses Jint to execute a javascript file with a bunch of functions.

The problem is that if there is

  • a syntax error
  • a runtime error
  • a throw new Error()

all you get out of Jint is a JavaScriptException with no context as to where the error occurred.

Right now I'm relegated to adding log statements just to find the problem in the script.

It would be extremely helpful if any throwing of Error() would come with the stack property filled in with the stacktrace of the js functions.

Most helpful comment

I had the same problem, where some long scripts would be extremely hard to debug. What we did is wrap Engine.Execute in our own try block, and re-throw with the Engine.GetLastSyntaxNode().Location.Start values. Example:

c# var engine = new Engine(); try { engine.Execute("some code that throws..."); } catch(JavaScriptException exc) { var location = engine.GetLastSyntaxNode().Location.Start; throw new ApplicationException( String.Format("{0} (Line {1}, Column {2})", exc.Error, location.Line, location.Column ), exc); }

Note that it would be much better if the location object was _always_ part of the JavaScriptException object.

All 3 comments

I had the same problem, where some long scripts would be extremely hard to debug. What we did is wrap Engine.Execute in our own try block, and re-throw with the Engine.GetLastSyntaxNode().Location.Start values. Example:

c# var engine = new Engine(); try { engine.Execute("some code that throws..."); } catch(JavaScriptException exc) { var location = engine.GetLastSyntaxNode().Location.Start; throw new ApplicationException( String.Format("{0} (Line {1}, Column {2})", exc.Error, location.Line, location.Column ), exc); }

Note that it would be much better if the location object was _always_ part of the JavaScriptException object.

Thanks, that is very helpful.

I still think it would be very valuable to have a stacktrace available. The reason is that (in my case) the script is dynamically assembled, so getting from a line number to the actual line in the dynamic script takes a little extra work.

For some parsing errors I encountered also the Esprima.ParserException exception.
And I found useful to add also the text of the line causing the error (as printed in ClearScript exception)

public void Run(string script)
{
    JintEngine.Execute(script);

    catch (Esprima.ParserException ex)
    {
        throw new ApplicationException($"{ex.Error} (Line {ex.LineNumber}, Column {ex.Column}), -> {ReadLine(script, ex.LineNumber)})", ex);
    }
    catch (Jint.Runtime.JavaScriptException ex) 
    {
        throw new ApplicationException($"{ex.Error} (Line {ex.LineNumber}, Column {ex.Column}), -> {ReadLine(script, ex.LineNumber)})", ex);
    }
}

private static string ReadLine(string text, int lineNumber)
{
    using var reader = new System.IO.StringReader(text);

    string line;
    int currentLineNumber = 0;

    do
    {
        currentLineNumber += 1;
        line = reader.ReadLine();
    }
    while (line != null && currentLineNumber < lineNumber);

    return (currentLineNumber == lineNumber) ? line : string.Empty;
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jugolo picture Jugolo  ·  13Comments

lahma picture lahma  ·  15Comments

mikeswanson picture mikeswanson  ·  3Comments

christianscheuer picture christianscheuer  ·  5Comments

shestakov picture shestakov  ·  10Comments