diff options
author | Dmitry Volyntsev <xeioex@nginx.com> | 2025-02-21 20:40:14 -0800 |
---|---|---|
committer | Dmitry Volyntsev <xeioexception@gmail.com> | 2025-02-24 16:49:43 -0800 |
commit | 24633b3766df99de3c138ca6dc37b0cb403e619d (patch) | |
tree | 193e764d13be211cd483e057f8972bee8ef6ac00 /nginx/ngx_js.c | |
parent | 89634204c4b12f17bbec826768d0d4e9dc5fae6c (diff) | |
download | njs-24633b3766df99de3c138ca6dc37b0cb403e619d.tar.gz njs-24633b3766df99de3c138ca6dc37b0cb403e619d.zip |
Modules: improved reporting of unhandled promise rejections.
Previously, some promise rejections were not reported.
For example:
async function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('timeout'));
}, ms);
});
}
async function handler(r) {
let v = await timeout(1000);
r.return(200);
}
Diffstat (limited to 'nginx/ngx_js.c')
-rw-r--r-- | nginx/ngx_js.c | 72 |
1 files changed, 23 insertions, 49 deletions
diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 7f7b7362..383d2304 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -731,13 +731,6 @@ ngx_engine_njs_call(ngx_js_ctx_t *ctx, ngx_str_t *fname, } } - if (ngx_js_unhandled_rejection(ctx)) { - ngx_js_exception(vm, &exception); - - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, "js exception: %V", &exception); - return NGX_ERROR; - } - return njs_rbtree_is_empty(&ctx->waiting_events) ? NGX_OK : NGX_AGAIN; } @@ -775,6 +768,7 @@ static void ngx_engine_njs_destroy(ngx_engine_t *e, ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *conf) { + ngx_str_t exception; ngx_js_event_t *event; njs_rbtree_node_t *node; @@ -791,6 +785,12 @@ ngx_engine_njs_destroy(ngx_engine_t *e, ngx_js_ctx_t *ctx, node = njs_rbtree_node_successor(&ctx->waiting_events, node); } + + if (ngx_js_unhandled_rejection(ctx)) { + ngx_js_exception(e->u.njs.vm, &exception); + ngx_log_error(NGX_LOG_ERR, ctx->log, 0, + "js unhandled rejection: %V", &exception); + } } njs_vm_destroy(e->u.njs.vm); @@ -1071,13 +1071,6 @@ ngx_engine_qjs_call(ngx_js_ctx_t *ctx, ngx_str_t *fname, } } - if (ngx_qjs_unhandled_rejection(ctx)) { - ngx_qjs_exception(ctx->engine, &exception); - - ngx_log_error(NGX_LOG_ERR, ctx->log, 0, "js exception: %V", &exception); - return NGX_ERROR; - } - return njs_rbtree_is_empty(&ctx->waiting_events) ? NGX_OK : NGX_AGAIN; } @@ -1129,16 +1122,16 @@ void ngx_engine_qjs_destroy(ngx_engine_t *e, ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *conf) { - uint32_t i, length; - JSRuntime *rt; - JSContext *cx; - JSClassID class_id; - ngx_qjs_event_t *event; - ngx_js_opaque_t *opaque; - njs_rbtree_node_t *node; - ngx_pool_cleanup_t *cln; - ngx_js_code_entry_t *pc; - ngx_js_rejected_promise_t *rejected_promise; + uint32_t i, length; + ngx_str_t exception; + JSRuntime *rt; + JSContext *cx; + JSClassID class_id; + ngx_qjs_event_t *event; + ngx_js_opaque_t *opaque; + njs_rbtree_node_t *node; + ngx_pool_cleanup_t *cln; + ngx_js_code_entry_t *pc; cx = e->u.qjs.ctx; @@ -1156,13 +1149,10 @@ ngx_engine_qjs_destroy(ngx_engine_t *e, ngx_js_ctx_t *ctx, node = njs_rbtree_node_successor(&ctx->waiting_events, node); } - if (ctx->rejected_promises != NULL) { - rejected_promise = ctx->rejected_promises->start; - - for (i = 0; i < ctx->rejected_promises->items; i++) { - JS_FreeValue(cx, ngx_qjs_arg(rejected_promise[i].promise)); - JS_FreeValue(cx, ngx_qjs_arg(rejected_promise[i].message)); - } + if (ngx_qjs_unhandled_rejection(ctx)) { + ngx_qjs_exception(ctx->engine, &exception); + ngx_log_error(NGX_LOG_ERR, ctx->log, 0, + "js unhandled rejection: %V", &exception); } class_id = JS_GetClassID(ngx_qjs_arg(ctx->args[0])); @@ -2037,10 +2027,8 @@ ngx_qjs_module_loader(JSContext *cx, const char *module_name, void *opaque) static int ngx_qjs_unhandled_rejection(ngx_js_ctx_t *ctx) { - size_t len; uint32_t i; JSContext *cx; - const char *str; ngx_js_rejected_promise_t *rejected_promise; if (ctx->rejected_promises == NULL @@ -2052,13 +2040,7 @@ ngx_qjs_unhandled_rejection(ngx_js_ctx_t *ctx) cx = ctx->engine->u.qjs.ctx; rejected_promise = ctx->rejected_promises->start; - str = JS_ToCStringLen(cx, &len, ngx_qjs_arg(rejected_promise->message)); - if (njs_slow_path(str == NULL)) { - return -1; - } - - JS_ThrowTypeError(cx, "unhandled promise rejection: %.*s", (int) len, str); - JS_FreeCString(cx, str); + JS_Throw(cx, JS_DupValue(cx, ngx_qjs_arg(rejected_promise->message))); for (i = 0; i < ctx->rejected_promises->items; i++) { JS_FreeValue(cx, ngx_qjs_arg(rejected_promise[i].promise)); @@ -3890,8 +3872,6 @@ static njs_int_t ngx_js_unhandled_rejection(ngx_js_ctx_t *ctx) { njs_vm_t *vm; - njs_int_t ret; - njs_str_t message; ngx_js_rejected_promise_t *rejected_promise; if (ctx->rejected_promises == NULL @@ -3903,13 +3883,7 @@ ngx_js_unhandled_rejection(ngx_js_ctx_t *ctx) vm = ctx->engine->u.njs.vm; rejected_promise = ctx->rejected_promises->start; - ret = njs_vm_value_to_string(vm, &message, - njs_value_arg(&rejected_promise->message)); - if (njs_slow_path(ret != NJS_OK)) { - return -1; - } - - njs_vm_error(vm, "unhandled promise rejection: %V", &message); + njs_vm_throw(vm, njs_value_arg(&rejected_promise->message)); njs_arr_destroy(ctx->rejected_promises); ctx->rejected_promises = NULL; |