Skip to content

Commit 5268179

Browse files
lolimmlostclaude
andcommitted
fix: Prevent sys.exit() from killing web UI when services are unreachable
wait_and_exit() called time.sleep() (blocking the async event loop) then sys.exit() which raised SystemExit — a BaseException that main_with_restart() didn't catch. This killed the entire process including the web UI. Now main_with_restart() catches non-zero SystemExit and restarts gracefully, and wait_and_exit() no longer blocks the event loop with time.sleep(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c63cec0 commit 5268179

2 files changed

Lines changed: 9 additions & 2 deletions

File tree

main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ async def main_with_restart():
111111
while True:
112112
try:
113113
await main()
114+
except SystemExit as e:
115+
if e.code == 0:
116+
raise # Clean shutdown (e.g. SIGTERM), don't restart
117+
logger.error("Main loop exited (unreachable service). Restarting in 30 seconds...")
118+
await asyncio.sleep(30)
114119
except Exception as e:
115120
logger.error(f"Main loop crashed: {e}. Restarting in 30 seconds...")
116121
await asyncio.sleep(30)

src/utils/common.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ async def make_request(
9191

9292
def wait_and_exit(seconds=30):
9393
logger.info(f"Decluttarr will wait for {seconds} seconds and then exit.")
94-
time.sleep(seconds)
95-
sys.exit()
94+
# Raise SystemExit instead of blocking with time.sleep(), so the async
95+
# event loop (and web UI) stays responsive. main_with_restart() catches
96+
# SystemExit and handles the retry delay.
97+
sys.exit(1)
9698

9799

98100
def extract_json_from_response(response, key: str | None = None):

0 commit comments

Comments
 (0)