Hi
js_std_promise_rejection_tracker trigger sync may cause problem
new Promise(() => {throw new Error(222)}).catch(e => console.log(e))
output with two error:
Possibly unhandled promise rejection: Error: some error
at <anonymous> (./hello.js)
at Promise (native)
at <eval> (./hello.js:39)
Error: some error
the correct output should be:
Error: some error
greets
Tony
-- snip --
diff --git a/quickjs-libc.c b/quickjs-libc.c
index 4e6d221..e96dc80 100644
--- a/quickjs-libc.c
+++ b/quickjs-libc.c
@@ -84,6 +84,15 @@ typedef struct {
JSValue func;
} JSOSTimer;
+typedef struct
+{
+ struct list_head link;
+ JSValue promise;
+ JSValueConst reason;
+} JSUnCaughtPromiseReject;
+
+static struct list_head js_uncaught_promise_reject =
LIST_HEAD_INIT(js_uncaught_promise_reject);
+
/* initialize the lists so js_std_free_handlers() can always be called */
static struct list_head os_rw_handlers = LIST_HEAD_INIT(os_rw_handlers);
static struct list_head os_signal_handlers =
LIST_HEAD_INIT(os_signal_handlers);
@@ -2980,9 +2989,49 @@ void js_std_promise_rejection_tracker(JSContext
*ctx, JSValueConst promise,
JSValueConst reason,
BOOL is_handled, void *opaque)
{
- if (!is_handled) {
- fprintf(stderr, "Possibly unhandled promise rejection: ");
- js_std_dump_error1(ctx, reason);
+ if (!is_handled)
+ {
+ JSUnCaughtPromiseReject *jr;
+
+ jr = js_mallocz(ctx, sizeof(*jr));
+ if (!jr) {
+ return;
+ }
+ jr->reason = JS_DupValue(ctx, reason);
+ jr->promise = JS_DupValue(ctx, promise);
+ list_add_tail(&jr->link, &js_uncaught_promise_reject);
+ }
+
+ if (is_handled)
+ {
+ struct list_head *el, *el1;
+ list_for_each_safe(el, el1, &js_uncaught_promise_reject)
+ {
+ JSUnCaughtPromiseReject *jr = list_entry(el,
JSUnCaughtPromiseReject, link);
+
+ if (JS_VALUE_GET_OBJ(promise) ==
JS_VALUE_GET_OBJ(jr->promise)) {
+ list_del(&jr->link);
+ JS_FreeValue(ctx, jr->promise);
+ JS_FreeValue(ctx, jr->reason);
+ js_free(ctx, jr);
+ }
+ }
+ }
+}
+
+void js_flush_uncaught_promise_rejection(JSContext *ctx)
+{
+ struct list_head *el, *el1;
+
+ list_for_each_safe(el, el1, &js_uncaught_promise_reject)
+ {
+ JSUnCaughtPromiseReject *jr = list_entry(el,
JSUnCaughtPromiseReject, link);
+ fprintf(stderr, "unhandled promise rejection: ");
+ js_std_dump_error1(ctx, jr->reason);
+ list_del(&jr->link);
+ JS_FreeValue(ctx, jr->promise);
+ JS_FreeValue(ctx, jr->reason);
+ js_free(ctx, jr);
}
}
@@ -3004,6 +3053,8 @@ void js_std_loop(JSContext *ctx)
}
}
+ js_flush_uncaught_promise_rejection(ctx);
+
if (!os_poll_func || os_poll_func(ctx))
break;
}