Browse Source

Add default 10 second timeout for promise unwrapping (#2103)

Marko Lahma 2 tháng trước cách đây
mục cha
commit
54a2801bf8

+ 3 - 3
Jint.Tests/Runtime/TestClasses/AsyncTestClass.cs

@@ -8,14 +8,14 @@ internal class AsyncTestClass
 
     public async Task AddToStringDelayedAsync(string appendWith)
     {
-        await Task.Delay(1000).ConfigureAwait(false);
+        await Task.Delay(100).ConfigureAwait(false);
 
         StringToAppend += appendWith;
     }
 
     public async Task<string> ReturnDelayedTaskAsync()
     {
-        await Task.Delay(1000).ConfigureAwait(false);
+        await Task.Delay(100).ConfigureAwait(false);
 
         return TestString;
     }
@@ -36,4 +36,4 @@ internal class AsyncTestClass
 
         throw new Exception("Task threw exception");
     }
-}
+}

+ 20 - 2
Jint/JsValueExtensions.cs

@@ -645,14 +645,32 @@ public static class JsValueExtensions
     /// </summary>
     /// <param name="value">value to unwrap</param>
     /// <returns>inner value if Promise the value itself otherwise</returns>
-    public static JsValue UnwrapIfPromise(this JsValue value)
+    public static JsValue UnwrapIfPromise(this JsValue value) => UnwrapIfPromise(value, TimeSpan.FromSeconds(10));
+
+    /// <summary>
+    /// If the value is a Promise
+    ///     1. If "Fulfilled" returns the value it was fulfilled with
+    ///     2. If "Rejected" throws "PromiseRejectedException" with the rejection reason
+    ///     3. If "Pending" throws "InvalidOperationException". Should be called only in "Settled" state
+    /// Else
+    ///     returns the value intact
+    /// </summary>
+    /// <param name="value">value to unwrap</param>
+    /// <param name="timeout">timeout to wait</param>
+    /// <returns>inner value if Promise the value itself otherwise</returns>
+    public static JsValue UnwrapIfPromise(this JsValue value, TimeSpan timeout)
     {
         if (value is JsPromise promise)
         {
             var engine = promise.Engine;
             var completedEvent = promise.CompletedEvent;
+
             engine.RunAvailableContinuations();
-            completedEvent.Wait();
+            if (!completedEvent.Wait(timeout))
+            {
+                ExceptionHelper.ThrowPromiseRejectedException($"Timeout of {timeout} reached");
+            }
+
             switch (promise.State)
             {
                 case PromiseState.Pending: