diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2021-08-26 22:47:00 -0700 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2021-08-27 21:29:28 -0700 |
commit | f478e264509d709ae9e8166525ae0f67b2e538e4 (patch) | |
tree | d0fccd7bc4874ededdc915861a483d70253d21d2 | |
parent | 7313e015247fd1746f3e9c1fc2420b48d5029643 (diff) | |
download | gjs-f478e264509d709ae9e8166525ae0f67b2e538e4.tar.gz |
function: Warn about unhandled promise rejections in System.exit()
If we ran System.exit() inside a signal handler, then we do an abrupt exit
without shutting down the JS engine. This means that we previously
would swallow warnings about unhandled promise rejections when exiting
from a signal handler. Instead, print them.
See discussion in #417 for more info.
-rw-r--r-- | gi/function.cpp | 2 | ||||
-rw-r--r-- | gjs/context-private.h | 3 | ||||
-rwxr-xr-x | installed-tests/scripts/testCommandLine.sh | 20 |
3 files changed, 22 insertions, 3 deletions
diff --git a/gi/function.cpp b/gi/function.cpp index 4c9c649a..25fea26f 100644 --- a/gi/function.cpp +++ b/gi/function.cpp @@ -376,6 +376,8 @@ void GjsCallbackTrampoline::callback_closure(GIArgument** args, void* result) { // main loop, or maybe not, but there's no way to tell, so we have // to exit here instead of propagating the exception back to the // original calling JS code. + gjs->warn_about_unhandled_promise_rejections(); + uint8_t code; if (gjs->should_exit(&code)) exit(code); diff --git a/gjs/context-private.h b/gjs/context-private.h index e29b495c..75b04bf0 100644 --- a/gjs/context-private.h +++ b/gjs/context-private.h @@ -136,8 +136,6 @@ class GjsContextPrivate : public JS::JobQueue { void stop_draining_job_queue(void); static gboolean drain_job_queue_idle_handler(void* data); - void warn_about_unhandled_promise_rejections(void); - uint8_t handle_exit_code(const char* type, const char* identifier, GError** error); [[nodiscard]] bool auto_profile_enter(void); @@ -245,6 +243,7 @@ class GjsContextPrivate : public JS::JobQueue { GJS_JSAPI_RETURN_CONVENTION bool run_jobs_fallible(void); void register_unhandled_promise_rejection(uint64_t id, GjsAutoChar&& stack); void unregister_unhandled_promise_rejection(uint64_t id); + void warn_about_unhandled_promise_rejections(); void register_notifier(DestroyNotify notify_func, void* data); void unregister_notifier(DestroyNotify notify_func, void* data); diff --git a/installed-tests/scripts/testCommandLine.sh b/installed-tests/scripts/testCommandLine.sh index 10eaea26..62be8243 100755 --- a/installed-tests/scripts/testCommandLine.sh +++ b/installed-tests/scripts/testCommandLine.sh @@ -103,6 +103,17 @@ const loop = new GLib.MainLoop(null, false); loop.run(); EOF +# this is similar to exit.js but should exit with an unhandled promise rejection +cat <<EOF >promiseexit.js +const {GLib} = imports.gi; +const System = imports.system; +const loop = GLib.MainLoop.new(null, false); +Promise.reject(); +GLib.idle_add(GLib.PRIORITY_LOW, () => System.exit(42)); +GLib.timeout_add_seconds(GLib.PRIORITY_HIGH, 3, () => loop.quit()); +loop.run(); +EOF + total=0 report () { @@ -156,8 +167,14 @@ if test -z $VALGRIND; then ASAN_OPTIONS=detect_leaks=0 $gjs exit.js test $? -ne 0 report "System.exit() should still exit across an FFI boundary" + + # https://gitlab.gnome.org/GNOME/gjs/-/issues/417 + output="$(ASAN_OPTIONS=detect_leaks=0 $gjs promiseexit.js 2>&1)" + test $? -ne 0 && printf '%s' "$output" | grep -q "Unhandled promise rejection" + report "Unhandled promise rejections should still be printed when exiting" else skip "System.exit() should still exit across an FFI boundary" "running under valgrind" + skip "Unhandled promise rejections should still be printed when exiting" "running under valgrind" fi # ensure the encoding of argv is being properly handled @@ -323,6 +340,7 @@ else skip "exit after first System.exit call in a signal callback" "running under valgrind" fi -rm -f exit.js help.js promise.js awaitcatch.js doublegi.js argv.js signalexit.js +rm -f exit.js help.js promise.js awaitcatch.js doublegi.js argv.js \ + signalexit.js promiseexit.js echo "1..$total" |