Jint: エラーと例外からスタックトレースを取得する機能を追加してください

作成日 2014年11月12日  ·  3コメント  ·  ソース: sebastienros/jint

Jintを使用して一連の関数を含むjavascriptファイルを実行するエンジンを構築しています。

問題は、

  • 構文エラー
  • ランタイムエラー
  • 新しいError()をスローします

Jintから得られるのは、エラーが発生した場所に関するコンテキストのないJavaScriptExceptionだけです。

今のところ、スクリプトの問題を見つけるためだけにログステートメントを追加することになりました。

Error()をスローすると、js関数のスタックトレースで埋められたスタックプロパティが付属する場合に非常に役立ちます。

最も参考になるコメント

同じ問題が発生しました。長いスクリプトの中には、デバッグが非常に難しいものがあります。 Engine.Executeを独自のtryブロックでラップし、 Engine.GetLastSyntaxNode().Location.Start値で再スローします。 例:

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); }

locationオブジェクトがJavaScriptExceptionオブジェクトの_常に_部分であるとはるかに良いことに注意してください。

全てのコメント3件

同じ問題が発生しました。長いスクリプトの中には、デバッグが非常に難しいものがあります。 Engine.Executeを独自のtryブロックでラップし、 Engine.GetLastSyntaxNode().Location.Start値で再スローします。 例:

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); }

locationオブジェクトがJavaScriptExceptionオブジェクトの_常に_部分であるとはるかに良いことに注意してください。

おかげで、それは非常に役に立ちます。

スタックトレースを利用できるようにしておくことは、今でも非常に価値があると思います。 その理由は、(私の場合)スクリプトが動的にアセンブルされるため、動的スクリプトの行番号から実際の行に移動するには、少し余分な作業が必要になるためです。

一部の解析エラーでは、 Esprima.ParserException例外も発生しました。
また、エラーの原因となっている行のテキストも追加すると便利です(ClearScript例外で出力されます)。

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;
}
このページは役に立ちましたか?
0 / 5 - 0 評価