瀏覽代碼

Propagate interop exceptions from IndexDescriptor (#728)

Marko Lahma 5 年之前
父節點
當前提交
0f2c39b912
共有 2 個文件被更改,包括 45 次插入10 次删除
  1. 16 1
      Jint.Tests/Runtime/InteropTests.cs
  2. 29 9
      Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs

+ 16 - 1
Jint.Tests/Runtime/InteropTests.cs

@@ -1550,8 +1550,23 @@ namespace Jint.Tests.Runtime
             ");
         }
 
+        private class FailingObject2
+        {
+            public int this[int index] => throw new ArgumentException("index is bad", nameof(index));
+        }
+
+        [Fact]
+        public void ShouldPropagateIndexerExceptions()
+        {
+            var engine = new Engine();
+            engine.Execute(@"function f2(obj) { return obj[1]; }");
+
+            var failingObject = new FailingObject2();
+            Assert.Throws<ArgumentException>(() => engine.Invoke("f2", failingObject));
+        }
+
         [Fact]
-        public void ShouldAutomaticallyConvertArraysToFindBestInteropResulution()
+        public void ShouldAutomaticallyConvertArraysToFindBestInteropResolution()
         {
             _engine.SetValue("a", new ArrayConverterTestClass());
             _engine.SetValue("item1", new ArrayConverterItem(1));

+ 29 - 9
Jint/Runtime/Descriptors/Specialized/IndexDescriptor.cs

@@ -25,7 +25,7 @@ namespace Jint.Runtime.Descriptors.Specialized
 
             Writable = engine.Options._IsClrWriteAllowed;
         }
-        
+
         public IndexDescriptor(Engine engine, string key, object item)
             : this(engine, item.GetType(), key, item)
         {
@@ -34,9 +34,9 @@ namespace Jint.Runtime.Descriptors.Specialized
         internal static bool TryFindIndexer(
             Engine engine,
             Type targetType,
-            string propertyName, 
+            string propertyName,
             out PropertyInfo indexerProperty,
-            out MethodInfo containsKeyMethod, 
+            out MethodInfo containsKeyMethod,
             out object indexerKey)
         {
             // get all instance indexers with exactly 1 argument
@@ -83,7 +83,7 @@ namespace Jint.Runtime.Descriptors.Specialized
                     ExceptionHelper.ThrowInvalidOperationException("Indexer has no public getter.");
                 }
 
-                object[] parameters = {_key};
+                object[] parameters = { _key };
 
                 if (_containsKey != null)
                 {
@@ -97,12 +97,21 @@ namespace Jint.Runtime.Descriptors.Specialized
                 {
                     return JsValue.FromObject(_engine, getter.Invoke(_target, parameters));
                 }
-                catch
+                catch (TargetInvocationException tie)
                 {
-                    return JsValue.Undefined;
+                    switch (tie.InnerException)
+                    {
+                        case null:
+                            throw;
+                        case ArgumentOutOfRangeException _:
+                            return JsValue.Undefined;
+                        case IndexOutOfRangeException _:
+                            return JsValue.Undefined;
+                        default:
+                            throw tie.InnerException;
+                    }
                 }
             }
-
             set
             {
                 var setter = _indexer.GetSetMethod();
@@ -111,8 +120,19 @@ namespace Jint.Runtime.Descriptors.Specialized
                     ExceptionHelper.ThrowInvalidOperationException("Indexer has no public setter.");
                 }
 
-                object[] parameters = {_key, value?.ToObject()};
-                setter.Invoke(_target, parameters);
+                object[] parameters = { _key,  value?.ToObject() };
+                try
+                {
+                    setter!.Invoke(_target, parameters);
+                }
+                catch (TargetInvocationException tie)
+                {
+                    if (tie.InnerException != null)
+                    {
+                        throw tie.InnerException;
+                    }
+                    throw;
+                }
             }
         }
     }