}
}
- 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;
}
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;
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);
}
}
- 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;
}
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;
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]));
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
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));
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
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;
location /set_rv_var {
return 200 $test_set_rv_var;
}
+
+ location /await_reject {
+ js_content test.await_reject;
+ }
}
}
r.setReturnValue(`retval: \${a1 + a2}`);
}
+ async function timeout(ms) {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ reject(new Error('timeout'));
+ }, ms);
+ });
+ }
+
+ async function await_reject(r) {
+ let v = await timeout(1);
+ r.return(200);
+ }
+
export default {njs:test_njs, set_timeout, set_timeout_data,
set_timeout_many, context_var, shared_ctx, limit_rate,
- async_content, set_rv_var};
+ async_content, set_rv_var, await_reject};
EOF
-$t->try_run('no njs available')->plan(9);
+$t->try_run('no njs available')->plan(10);
###############################################################################
like(http_get('/set_rv_var'), qr/retval: 30/, 'set return value variable');
http_get('/async_var');
+http_get('/await_reject');
$t->stop();
'pending js events');
ok(index($t->read_file('error.log'), 'async operation inside') > 0,
'async op in var handler');
+ok(index($t->read_file('error.log'), 'js unhandled rejection') > 0,
+ 'unhandled rejection');
###############################################################################