[njs] Fixed catching of the exception thrown from an awaited function.
Dmitry Volyntsev
xeioex at nginx.com
Wed Jun 1 04:53:56 UTC 2022
details: https://hg.nginx.org/njs/rev/2774fed7b864
branches:
changeset: 1871:2774fed7b864
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue May 31 21:48:46 2022 -0700
description:
Fixed catching of the exception thrown from an awaited function.
This closes #500 issue on Github.
diffstat:
src/njs_async.c | 6 +++---
test/js/async_try_catch_call.t.js | 29 +++++++++++++++++++++++++++++
test/js/async_try_catch_expression.t.js | 28 ++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 3 deletions(-)
diffs (95 lines):
diff -r bd520efc0df1 -r 2774fed7b864 src/njs_async.c
--- a/src/njs_async.c Tue May 31 21:48:26 2022 -0700
+++ b/src/njs_async.c Tue May 31 21:48:46 2022 -0700
@@ -67,9 +67,6 @@ njs_await_fulfilled(njs_vm_t *vm, njs_va
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_val
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_val
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 -r bd520efc0df1 -r 2774fed7b864 test/js/async_try_catch_call.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/async_try_catch_call.t.js Tue May 31 21:48:46 2022 -0700
@@ -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 -r bd520efc0df1 -r 2774fed7b864 test/js/async_try_catch_expression.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/async_try_catch_expression.t.js Tue May 31 21:48:46 2022 -0700
@@ -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)
More information about the nginx-devel
mailing list