]> git.kaiwu.me - njs.git/commitdiff
Fixed catching of the exception thrown from an awaited function.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 1 Jun 2022 04:48:46 +0000 (21:48 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 1 Jun 2022 04:48:46 +0000 (21:48 -0700)
This closes #500 issue on Github.

src/njs_async.c
test/js/async_try_catch_call.t.js [new file with mode: 0644]
test/js/async_try_catch_expression.t.js [new file with mode: 0644]

index e018bd8b643da682b9f6d0ccf8d2999ae759cf93..380c44b7cbb3d9f6db55c0cfd6b997b5d66db131 100644 (file)
@@ -67,9 +67,6 @@ njs_await_fulfilled(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     ctx = vm->top_frame->function->context;
 
     value = njs_arg(args, nargs, 1);
-    if (njs_is_error(value)) {
-        goto failed;
-    }
 
     async_frame = ctx->await;
     async = &async_frame->native;
@@ -143,6 +140,7 @@ njs_await_rejected(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     value = njs_arg(args, nargs, 1);
 
     if (ctx->await->native.pc == ctx->pc) {
+        /* No catch block was set before await. */
         (void) njs_function_call(vm, njs_function(&ctx->capability->reject),
                                  &njs_value_undefined, value, 1, &vm->retval);
 
@@ -151,6 +149,8 @@ njs_await_rejected(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
+    /* ctx->await->native.pc points to a catch block here. */
+
     ctx->pc = ctx->await->native.pc;
 
     return njs_await_fulfilled(vm, args, nargs, unused);
diff --git a/test/js/async_try_catch_call.t.js b/test/js/async_try_catch_call.t.js
new file mode 100644 (file)
index 0000000..6e8ef10
--- /dev/null
@@ -0,0 +1,29 @@
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+const fn = async () => { throw new Error('Oops') };
+
+async function af() {
+    try {
+        await fn();
+
+        $DONOTEVALUATE();
+    }
+    catch (v) {
+        stages.push(`catch:${v}`);
+    }
+    finally {
+        stages.push('finally');
+    }
+
+    return "end";
+};
+
+af().then(v => {
+    stages.push(v);
+    assert.compareArray(stages, ['catch:Error: Oops', 'finally', 'end']);
+})
+.then($DONE, $DONE)
diff --git a/test/js/async_try_catch_expression.t.js b/test/js/async_try_catch_expression.t.js
new file mode 100644 (file)
index 0000000..58d0420
--- /dev/null
@@ -0,0 +1,28 @@
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+async function af() {
+    try {
+        await ({}).a.a();
+
+        $DONOTEVALUATE();
+    }
+    catch (v) {
+        stages.push('catch');
+    }
+    finally {
+        stages.push('finally');
+    }
+
+    return "end";
+};
+
+af().then(v => {
+    stages.push(v);
+    assert.compareArray(stages, ['catch', 'finally', 'end']);
+})
+.then($DONE, $DONE)