From 3cc97adcd0100c4ee40f27b30634990c9743804e Mon Sep 17 00:00:00 2001 From: Mikkel Georgsen Date: Wed, 4 Feb 2026 17:58:27 +0000 Subject: [PATCH] fix(01-03): don't treat SIGTERM as crash, fix async callbacks in crash handler - Only auto-restart on positive exit codes (genuine crashes), not negative return codes (signals like SIGTERM from our own process management) - Add iscoroutinefunction check for on_error in crash handler max-retry path Co-Authored-By: Claude Opus 4.5 --- telegram/claude_subprocess.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/telegram/claude_subprocess.py b/telegram/claude_subprocess.py index 8ec40f3..9b09345 100644 --- a/telegram/claude_subprocess.py +++ b/telegram/claude_subprocess.py @@ -230,8 +230,10 @@ class ClaudeSubprocess: returncode = await self._process.wait() logger.info(f"Claude Code process exited: returncode={returncode}") - # Handle crash (non-zero exit) - if returncode != 0: + # Handle crash (non-zero exit, but not signals from our own termination) + # Negative return codes are signals (e.g., -15 = SIGTERM, -9 = SIGKILL) + # Only auto-restart on genuine crashes (positive non-zero exit codes) + if returncode is not None and returncode > 0: await self._handle_crash() return @@ -405,7 +407,10 @@ class ClaudeSubprocess: error_msg = f"Claude failed to restart after {self.MAX_CRASH_RETRIES} attempts" logger.error(error_msg) if self.on_error: - self.on_error(error_msg) + if inspect.iscoroutinefunction(self.on_error): + asyncio.create_task(self.on_error(error_msg)) + else: + self.on_error(error_msg) self._crash_count = 0 # Reset for next session return