Browse Source

Throw real JavascriptException location on Module (#1522)

李凤焕 2 years ago
parent
commit
65606532ef

+ 17 - 0
Jint.Tests/Runtime/ErrorTests.cs

@@ -459,6 +459,23 @@ $variable1 + -variable2 - variable3;");
             Assert.Equal("foo is not defined", exception.Message);
             Assert.Equal("foo is not defined", exception.Message);
         }
         }
 
 
+        [Fact]
+        public void JavaScriptExceptionLocationOnModuleShouldBeRight()
+        {
+            var engine = new Engine();
+            engine.AddModule("my_module", @"
+function throw_error(){
+    throw Error(""custom error"")
+}
+
+throw_error();
+            ");
+
+            var ex= Assert.Throws<JavaScriptException>(() => engine.ImportModule("my_module"));
+            Assert.Equal(ex.Location.Start.Line, 3);
+            Assert.Equal(ex.Location.Start.Column, 10);
+        }
+
         private static void EqualIgnoringNewLineDifferences(string expected, string actual)
         private static void EqualIgnoringNewLineDifferences(string expected, string actual)
         {
         {
             expected = expected.Replace("\r\n", "\n");
             expected = expected.Replace("\r\n", "\n");

+ 5 - 1
Jint/Engine.Modules.cs

@@ -154,7 +154,11 @@ namespace Jint
             }
             }
             else if (promise.State == PromiseState.Rejected)
             else if (promise.State == PromiseState.Rejected)
             {
             {
-                var node = EsprimaExtensions.CreateLocationNode(Location.From(new Position(), new Position(), specifier));
+                var location = cyclicModule is CyclicModuleRecord cyclicModuleRecord
+                    ? cyclicModuleRecord.AbnormalCompletionLocation
+                    : Location.From(new Position(), new Position());
+
+                var node = EsprimaExtensions.CreateLocationNode(location);
                 ExceptionHelper.ThrowJavaScriptException(this, promise.Value, node.Location);
                 ExceptionHelper.ThrowJavaScriptException(this, promise.Value, node.Location);
             }
             }
             else if (promise.State != PromiseState.Fulfilled)
             else if (promise.State != PromiseState.Fulfilled)

+ 5 - 1
Jint/Runtime/Modules/CyclicModuleRecord.cs

@@ -1,5 +1,6 @@
 #nullable disable
 #nullable disable
 
 
+using Esprima;
 using Esprima.Ast;
 using Esprima.Ast;
 using Jint.Native;
 using Jint.Native;
 using Jint.Native.Promise;
 using Jint.Native.Promise;
@@ -40,6 +41,8 @@ public abstract class CyclicModuleRecord : ModuleRecord
 
 
     internal ModuleStatus Status { get; private set; }
     internal ModuleStatus Status { get; private set; }
 
 
+    internal Location AbnormalCompletionLocation { get; private set; }
+
     /// <summary>
     /// <summary>
     /// https://tc39.es/ecma262/#sec-moduledeclarationlinking
     /// https://tc39.es/ecma262/#sec-moduledeclarationlinking
     /// </summary>
     /// </summary>
@@ -121,7 +124,7 @@ public abstract class CyclicModuleRecord : ModuleRecord
         module._topLevelCapability = capability;
         module._topLevelCapability = capability;
 
 
         var result = module.InnerModuleEvaluation(stack, 0, ref asyncEvalOrder);
         var result = module.InnerModuleEvaluation(stack, 0, ref asyncEvalOrder);
-
+        
         if (result.Type != CompletionType.Normal)
         if (result.Type != CompletionType.Normal)
         {
         {
             foreach (var m in stack)
             foreach (var m in stack)
@@ -130,6 +133,7 @@ public abstract class CyclicModuleRecord : ModuleRecord
                 m._evalError = result;
                 m._evalError = result;
             }
             }
 
 
+            AbnormalCompletionLocation = result.Location;
             capability.Reject.Call(Undefined, new[] { result.Value });
             capability.Reject.Call(Undefined, new[] { result.Value });
         }
         }
         else
         else