Jintを使用して一連の関数を含むjavascriptファイルを実行するエンジンを構築しています。
問題は、
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
オブジェクトの_常に_部分であるとはるかに良いことに注意してください。
おかげで、それは非常に役に立ちます。
スタックトレースを利用できるようにしておくことは、今でも非常に価値があると思います。 その理由は、(私の場合)スクリプトが動的にアセンブルされるため、動的スクリプトの行番号から実際の行に移動するには、少し余分な作業が必要になるためです。
一部の解析エラーでは、 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;
}
最も参考になるコメント
同じ問題が発生しました。長いスクリプトの中には、デバッグが非常に難しいものがあります。
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
オブジェクトの_常に_部分であるとはるかに良いことに注意してください。