أنا أقوم ببناء محرك يستخدم Jint لتنفيذ ملف جافا سكريبت مع مجموعة من الوظائف.
المشكلة هي أنه إذا كان هناك
كل ما تحصل عليه من Jint هو JavaScriptException بدون سياق يتعلق بمكان حدوث الخطأ.
في الوقت الحالي ، أُنزل إلى إضافة بيانات السجل فقط للعثور على المشكلة في البرنامج النصي.
سيكون من المفيد للغاية أن يأتي أي رمي للخطأ () مع خاصية المكدس مملوءة بتتبع تكديس وظائف 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
.