From ffb1095f2371b0accc25552ea94cd21b5ac47412 Mon Sep 17 00:00:00 2001 From: anthorob Date: Fri, 25 Sep 2026 06:46:31 -0400 Subject: [PATCH] Replace `System.exit` with exceptions for safer shutdown Refactored various parts of the application to replace calls to `System.exit` with appropriate `IllegalStateException` usage. Improved modularity and testability by delegating error handling to specific exception cases instead of terminating the JVM directly. Updated related components to ensure proper cleanup and graceful shutdown behavior during failures. --- src/main/java/me/bobert/netneutrality/App.java | 9 +++++++-- .../me/bobert/netneutrality/db/DatabaseMigration.java | 2 +- .../java/me/bobert/netneutrality/db/SessionManager.java | 2 +- .../bobert/netneutrality/http/server/ActionRoutes.java | 1 - 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/me/bobert/netneutrality/App.java b/src/main/java/me/bobert/netneutrality/App.java index 6cbd25a..01ff453 100644 --- a/src/main/java/me/bobert/netneutrality/App.java +++ b/src/main/java/me/bobert/netneutrality/App.java @@ -94,7 +94,9 @@ public class App { context.start(); } catch (Exception e) { LogHandler.log(e); - System.exit(1); + // Roll back the components that did start so no non-daemon thread keeps the JVM alive. + context.stop(); + throw new IllegalStateException("Startup failed", e); } Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown)); @@ -206,8 +208,11 @@ public class App { .build(); jda.awaitReady(); } catch (InvalidTokenException | IllegalArgumentException | InterruptedException e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } LogHandler.log(e); - System.exit(1); + throw new IllegalStateException("Unable to connect to Discord", e); } } diff --git a/src/main/java/me/bobert/netneutrality/db/DatabaseMigration.java b/src/main/java/me/bobert/netneutrality/db/DatabaseMigration.java index 9cb116e..90421b7 100644 --- a/src/main/java/me/bobert/netneutrality/db/DatabaseMigration.java +++ b/src/main/java/me/bobert/netneutrality/db/DatabaseMigration.java @@ -32,7 +32,7 @@ public class DatabaseMigration { logger.info("Database migrations finished successfully! (total: {})", result.migrationsExecuted); } catch (Exception e) { logger.error(e); - System.exit(1); + throw new IllegalStateException("Database migration failed", e); } } } diff --git a/src/main/java/me/bobert/netneutrality/db/SessionManager.java b/src/main/java/me/bobert/netneutrality/db/SessionManager.java index 96769b2..7e15023 100644 --- a/src/main/java/me/bobert/netneutrality/db/SessionManager.java +++ b/src/main/java/me/bobert/netneutrality/db/SessionManager.java @@ -89,7 +89,7 @@ public class SessionManager implements SessionProvider { stop(); logger.error("Error connecting to database. Shutting down.."); - System.exit(1); + throw new IllegalStateException("Unable to connect to the database", e); } } diff --git a/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java b/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java index f1d42da..7c7ef4c 100644 --- a/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java +++ b/src/main/java/me/bobert/netneutrality/http/server/ActionRoutes.java @@ -76,7 +76,6 @@ public final class ActionRoutes { Thread.currentThread().interrupt(); } shutdownHook.run(); - System.exit(0); }); } }