File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11import asyncio
22import logging
3+ from logging .handlers import RotatingFileHandler
34import os
45from typing import Optional
56
1314load_dotenv ()
1415
1516# Configure logging
17+ handlers : list [logging .Handler ] = [logging .StreamHandler ()]
18+
19+ # File logging is best-effort: some hosts have very limited disk.
20+ try :
21+ handlers .append (
22+ RotatingFileHandler (
23+ 'modmail_bot.log' ,
24+ maxBytes = 1_000_000 ,
25+ backupCount = 2 ,
26+ encoding = 'utf-8' ,
27+ delay = True ,
28+ )
29+ )
30+ except OSError :
31+ # Disk full / read-only FS / permission issue — continue with console logging.
32+ pass
33+
1634logging .basicConfig (
1735 level = getattr (logging , os .getenv ('LOG_LEVEL' , 'INFO' )),
1836 format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ,
19- handlers = [
20- logging .FileHandler ('modmail_bot.log' ),
21- logging .StreamHandler ()
22- ]
37+ handlers = handlers ,
2338)
39+
40+ # Prevent noisy "--- Logging error ---" tracebacks in production.
41+ logging .raiseExceptions = False
2442logger = logging .getLogger (__name__ )
2543
2644class ModMailBot (commands .Bot ):
Original file line number Diff line number Diff line change @@ -93,7 +93,13 @@ async def _load_sessions_from_file(self):
9393 try :
9494 async with aiofiles .open (self .SESSIONS_FILE , "r" , encoding = "utf-8" ) as fh :
9595 content = await fh .read ()
96- data = json .loads (content )
96+ if not content .strip ():
97+ return
98+ try :
99+ data = json .loads (content )
100+ except json .JSONDecodeError :
101+ logger .warning ("modmail: sessions file is not valid JSON; ignoring" )
102+ return
97103 for k , v in data .items ():
98104 try :
99105 self .modmail_sessions [int (k )] = v
@@ -106,8 +112,10 @@ async def _persist_sessions_to_file(self):
106112 try :
107113 self .SESSIONS_FILE .parent .mkdir (parents = True , exist_ok = True )
108114 dumpable = {str (k ): v for k , v in self .modmail_sessions .items ()}
109- async with aiofiles .open (self .SESSIONS_FILE , "w" , encoding = "utf-8" ) as fh :
115+ tmp_path = self .SESSIONS_FILE .with_suffix (self .SESSIONS_FILE .suffix + ".tmp" )
116+ async with aiofiles .open (tmp_path , "w" , encoding = "utf-8" ) as fh :
110117 await fh .write (json .dumps (dumpable ))
118+ tmp_path .replace (self .SESSIONS_FILE )
111119 except Exception :
112120 logger .exception ("modmail: failed to persist sessions to file" )
113121
You can’t perform that action at this time.
0 commit comments