]> git.kaiwu.me - njs.git/commitdiff
Fixed tracking of unhandled rejected promises.
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 19 Jan 2024 02:03:24 +0000 (18:03 -0800)
committerDmitry Volyntsev <xeioex@nginx.com>
Fri, 19 Jan 2024 02:03:24 +0000 (18:03 -0800)
Checking for unhandled promise rejections while looping for pending jobs
produces false-positive reports when an rejected promised is handled
by one of the pending jobs later.

The fix is to check for unhandled promise rejections only at top level
calls like ngx_js_name_invoke() and ngx_js_name_call() and only after
all pending jobs are processed.

The issue was introduced in bc80bcb3102c (not released yet).

external/njs_shell.c
nginx/ngx_js.c
src/test/njs_externals_test.c
src/test/njs_unit_test.c

index 1eb554fe061b6c69acdb013ba3dc0a2361ec552f..ba68f0f8c1cfbd6a50e90a50e6bdf921793c2d52 100644 (file)
@@ -1100,7 +1100,7 @@ njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
         for ( ;; ) {
             ret = njs_vm_execute_pending_job(vm);
             if (ret <= NJS_OK) {
-                if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+                if (ret == NJS_ERROR) {
                     njs_process_output(vm, NULL, ret);
 
                     if (!njs_vm_options(vm)->interactive) {
@@ -1112,6 +1112,14 @@ njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
             }
         }
 
+        if (njs_vm_unhandled_rejection(vm)) {
+            njs_process_output(vm, NULL, NJS_ERROR);
+
+            if (!njs_vm_options(vm)->interactive) {
+                return NJS_ERROR;
+            }
+        }
+
         ret = njs_process_events(runtime);
         if (njs_slow_path(ret == NJS_ERROR)) {
             break;
index 486c1cae58f182e0a888bd4e66a39ffd054aa383..6ebc873b09c08efc462d7cbcb1339ee2d9cfc218 100644 (file)
@@ -357,7 +357,7 @@ ngx_js_call(njs_vm_t *vm, njs_function_t *func, njs_value_t *args,
         if (ret <= NJS_OK) {
             c = ngx_external_connection(vm, njs_vm_external_ptr(vm));
 
-            if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+            if (ret == NJS_ERROR) {
                 ngx_js_exception(vm, &exception);
 
                 ngx_log_error(NGX_LOG_ERR, c->log, 0,
@@ -417,7 +417,7 @@ ngx_js_name_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
     for ( ;; ) {
         ret = njs_vm_execute_pending_job(vm);
         if (ret <= NJS_OK) {
-            if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+            if (ret == NJS_ERROR) {
                 ngx_js_exception(vm, &exception);
 
                 ngx_log_error(NGX_LOG_ERR, log, 0,
@@ -429,6 +429,13 @@ ngx_js_name_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
         }
     }
 
+    if (njs_vm_unhandled_rejection(vm)) {
+        ngx_js_exception(vm, &exception);
+
+        ngx_log_error(NGX_LOG_ERR, log, 0, "js exception: %V", &exception);
+        return NGX_ERROR;
+    }
+
     ctx = ngx_external_ctx(vm, njs_vm_external_ptr(vm));
 
     return njs_rbtree_is_empty(&ctx->waiting_events) ? NGX_OK : NGX_AGAIN;
index 58b888a6d67bc8b8d38f13c3664b2f540dcf8c67..f9fa6dbf50aa31e09e69105ede451b31ce11d9ec 100644 (file)
@@ -1485,7 +1485,7 @@ njs_external_call(njs_vm_t *vm, const njs_str_t *fname, njs_value_t *args,
     for ( ;; ) {
         ret = njs_vm_execute_pending_job(vm);
         if (ret <= NJS_OK) {
-            if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) {
+            if (ret == NJS_ERROR) {
                 return NJS_ERROR;
             }
 
index 8561bfcf5493da0969edb91a0e86cda508310949..1c029f8fa5b46902d252a01330fae5c872f6c638 100644 (file)
@@ -23708,9 +23708,7 @@ njs_process_test(njs_external_state_t *state, njs_opts_t *opts,
             for ( ;; ) {
                 ret = njs_vm_execute_pending_job(state->vm);
                 if (ret <= NJS_OK) {
-                    if (ret == NJS_ERROR
-                        || njs_vm_unhandled_rejection(state->vm))
-                    {
+                    if (ret == NJS_ERROR) {
                         return NJS_ERROR;
                     }