[gjs/ewlsh/top-level-await-mainloop] Refactor exit code handling for async exceptions




commit 6f8139e511d5868d1c9fa20436b53b50a02875d9
Author: Evan Welsh <contact evanwelsh com>
Date:   Sat Nov 6 19:16:48 2021 -0700

    Refactor exit code handling for async exceptions

 gjs/context-private.h                             |  5 +-
 gjs/context.cpp                                   | 63 +++++++++++++----------
 installed-tests/scripts/testCommandLineModules.sh |  4 +-
 3 files changed, 41 insertions(+), 31 deletions(-)
---
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 48394b4d..b2cbf50d 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -139,8 +139,9 @@ class GjsContextPrivate : public JS::JobQueue {
     void start_draining_job_queue(void);
     void stop_draining_job_queue(void);
 
-    uint8_t handle_exit_code(const char* type, const char* identifier,
-                             GError** error);
+    bool handle_exit_code(bool has_sync_error, const char* type,
+                          const char* identifier, uint8_t* exit_code,
+                          GError** error);
     [[nodiscard]] bool auto_profile_enter(void);
     void auto_profile_exit(bool status);
 
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 332d9291..ac1a620b 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -1214,31 +1214,46 @@ void GjsContextPrivate::auto_profile_exit(bool auto_profile) {
         gjs_profiler_stop(m_profiler);
 }
 
-uint8_t GjsContextPrivate::handle_exit_code(const char* type,
-                                            const char* identifier,
-                                            GError** error) {
+bool GjsContextPrivate::handle_exit_code(bool has_sync_error, const char* type,
+                                         const char* identifier,
+                                         uint8_t* exit_code, GError** error) {
     uint8_t code;
     if (should_exit(&code)) {
         /* exit_status_p is public API so can't be changed, but should be
          * uint8_t, not int */
         g_set_error(error, GJS_ERROR, GJS_ERROR_SYSTEM_EXIT,
                     "Exit with code %d", code);
-        return code;  // Don't log anything
+
+        *exit_code = code;
+        return false;  // Don't log anything
     }
-    if (!JS_IsExceptionPending(m_cx)) {
-        g_critical("%s %s terminated with an uncatchable exception", type,
-                   identifier);
-        g_set_error(error, GJS_ERROR, GJS_ERROR_FAILED,
-                    "%s %s terminated with an uncatchable exception", type,
-                    identifier);
-    } else {
+
+    if (JS_IsExceptionPending(m_cx)) {
         g_set_error(error, GJS_ERROR, GJS_ERROR_FAILED,
                     "%s %s threw an exception", type, identifier);
+        gjs_log_exception_uncaught(m_cx);
+
+        *exit_code = 1;
+        return false;
+    }
+
+    // Assume success if no error was thrown and should exit isn't
+    // set
+    if (!has_sync_error) {
+        *exit_code = 0;
+        return true;
     }
 
+    g_critical("%s %s terminated with an uncatchable exception", type,
+               identifier);
+    g_set_error(error, GJS_ERROR, GJS_ERROR_FAILED,
+                "%s %s terminated with an uncatchable exception", type,
+                identifier);
+
     gjs_log_exception_uncaught(m_cx);
     /* No exit code from script, but we don't want to exit(0) */
-    return 1;
+    *exit_code = 1;
+    return false;
 }
 
 bool GjsContextPrivate::eval(const char* script, ssize_t script_len,
@@ -1266,10 +1281,8 @@ bool GjsContextPrivate::eval(const char* script, ssize_t script_len,
 
     auto_profile_exit(auto_profile);
 
-    if (!ok) {
-        *exit_status_p = handle_exit_code("Script", filename, error);
-        return false;
-    }
+    uint8_t out_code;
+    ok = handle_exit_code(!ok, "Script", filename, &out_code, error);
 
     if (exit_status_p) {
         if (retval.isInt32()) {
@@ -1278,13 +1291,11 @@ bool GjsContextPrivate::eval(const char* script, ssize_t script_len,
                       "Script returned integer code %d", code);
             *exit_status_p = code;
         } else {
-            // Assume success if no integer was returned and should exit isn't
-            // set
-            *exit_status_p = 0;
+            *exit_status_p = out_code;
         }
     }
 
-    return true;
+    return ok;
 }
 
 bool GjsContextPrivate::eval_module(const char* identifier,
@@ -1329,14 +1340,12 @@ bool GjsContextPrivate::eval_module(const char* identifier,
 
     auto_profile_exit(auto_profile);
 
-    if (!ok) {
-        *exit_status_p = handle_exit_code("Module", identifier, error);
-        return false;
-    }
+    uint8_t out_code;
+    ok = handle_exit_code(!ok, "Module", identifier, &out_code, error);
+    if (exit_status_p)
+        *exit_status_p = out_code;
 
-    /* Assume success if no errors were thrown or exit code set. */
-    *exit_status_p = 0;
-    return true;
+    return ok;
 }
 
 bool GjsContextPrivate::register_module(const char* identifier, const char* uri,
diff --git a/installed-tests/scripts/testCommandLineModules.sh 
b/installed-tests/scripts/testCommandLineModules.sh
index fe2e9eb6..6566dcb7 100755
--- a/installed-tests/scripts/testCommandLineModules.sh
+++ b/installed-tests/scripts/testCommandLineModules.sh
@@ -77,7 +77,7 @@ test $? -eq 21
 report "ensure dynamic imports resolve without an explicit mainloop"
 
 
-# rm -f doubledynamic.js doubledynamicImportee.js \
-#       dynamicImplicitMainloop.js dynamicImplicitMainloopImportee.js
+rm -f doubledynamic.js doubledynamicImportee.js \
+      dynamicImplicitMainloop.js dynamicImplicitMainloopImportee.js
 
 echo "1..$total"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]