Ich baue eine Engine, die Jint verwendet, um eine Javascript-Datei mit einer Reihe von Funktionen auszuführen.
Das Problem ist, dass wenn es
Alles, was Sie aus Jint herausbekommen, ist eine JavaScriptException ohne Kontext, wo der Fehler aufgetreten ist.
Im Moment bin ich gezwungen, Protokollanweisungen hinzuzufügen, nur um das Problem im Skript zu finden.
Es wäre äußerst hilfreich, wenn beim Auslösen von Error() die Stack-Eigenschaft mit dem Stacktrace der js-Funktionen gefüllt wäre.
Ich hatte das gleiche Problem, bei dem einige lange Skripte extrem schwer zu debuggen wären. Was wir gemacht haben, ist Engine.Execute
in unseren eigenen try
Block einzuschließen und mit den Engine.GetLastSyntaxNode().Location.Start
Werten erneut zu werfen. Beispiel:
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);
}
Beachten Sie, dass es viel besser wäre, wenn das location
Objekt _immer_ Teil des JavaScriptException
Objekts wäre.
Danke, das ist sehr hilfreich.
Ich denke immer noch, dass es sehr wertvoll wäre, einen Stacktrace zur Verfügung zu haben. Der Grund dafür ist, dass das Skript (in meinem Fall) dynamisch zusammengestellt wird, sodass es etwas mehr Arbeit erfordert, von einer Zeilennummer zur eigentlichen Zeile im dynamischen Skript zu gelangen.
Bei einigen Parsing-Fehlern bin ich auch auf die Ausnahme Esprima.ParserException
gestoßen.
Und ich fand es nützlich, auch den Text der Zeile hinzuzufügen, die den Fehler verursacht (wie in der ClearScript-Ausnahme gedruckt)
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;
}
Hilfreichster Kommentar
Ich hatte das gleiche Problem, bei dem einige lange Skripte extrem schwer zu debuggen wären. Was wir gemacht haben, ist
Engine.Execute
in unseren eigenentry
Block einzuschließen und mit denEngine.GetLastSyntaxNode().Location.Start
Werten erneut zu werfen. Beispiel: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); }
Beachten Sie, dass es viel besser wäre, wenn das
location
Objekt _immer_ Teil desJavaScriptException
Objekts wäre.