Fix shutdown error: file descriptor cannot be a negative integer

Improved error handling in bot shutdown process:
- Check connection state before attempting to quit IRC
- Use thread-safe event loop shutdown
- Filter expected shutdown errors from error logs
- Changed shutdown errors to debug level logging

This prevents the "file descriptor cannot be a negative integer (-1)"
error from appearing as an ERROR when cleanly shutting down the bot.
This commit is contained in:
Claude 2026-01-02 21:06:47 +00:00
parent 1678702ef3
commit a52be47121
No known key found for this signature in database

View file

@ -232,9 +232,14 @@ class EugenBot(irc.bot.SingleServerIRCBot):
self.logger.info("Starting IRC bot...") self.logger.info("Starting IRC bot...")
super().start() super().start()
except Exception as e: except Exception as e:
self.logger.error(f"Bot error: {str(e)}") # Ignore errors related to shutdown (file descriptor issues)
error_msg = str(e)
if "file descriptor" in error_msg.lower() and not self.is_running:
self.logger.debug(f"Shutdown cleanup: {error_msg}")
else:
self.logger.error(f"Bot error: {error_msg}")
if self.dashboard: if self.dashboard:
self.dashboard.log_event("error", {"error": f"Bot crashed: {str(e)}"}) self.dashboard.log_event("error", {"error": f"Bot crashed: {error_msg}"})
def stop(self): def stop(self):
"""Stop the bot""" """Stop the bot"""
@ -243,14 +248,22 @@ class EugenBot(irc.bot.SingleServerIRCBot):
if self.dashboard: if self.dashboard:
self.dashboard.log_event("info", {"message": "Shutting down..."}) self.dashboard.log_event("info", {"message": "Shutting down..."})
# Safely disconnect from IRC
try: try:
if hasattr(self, 'connection') and self.connection and self.connection.connected:
self.connection.quit("Bot shutting down") self.connection.quit("Bot shutting down")
self.die() except Exception as e:
except: self.logger.debug(f"Error during disconnect: {str(e)}")
pass
if self.loop: # Stop IRC bot
self.loop.stop() try:
self.die()
except Exception as e:
self.logger.debug(f"Error during die(): {str(e)}")
# Stop event loop
if self.loop and self.loop.is_running():
self.loop.call_soon_threadsafe(self.loop.stop)
def check_env_file(): def check_env_file():