From: Dmitry Volyntsev Date: Fri, 19 Jan 2024 02:03:24 +0000 (-0800) Subject: Fixed tracking of unhandled rejected promises. X-Git-Tag: 0.8.3~13 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=e1120a2d82468fe7e403c12ab7b37e779f1160fd;p=njs.git Fixed tracking of unhandled rejected promises. 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). --- diff --git a/external/njs_shell.c b/external/njs_shell.c index 1eb554fe..ba68f0f8 100644 --- a/external/njs_shell.c +++ b/external/njs_shell.c @@ -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; diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 486c1cae..6ebc873b 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -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; diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c index 58b888a6..f9fa6dbf 100644 --- a/src/test/njs_externals_test.c +++ b/src/test/njs_externals_test.c @@ -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; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 8561bfcf..1c029f8f 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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; }