diff --git a/bot.py b/bot.py index 6883ee5..eca411f 100755 --- a/bot.py +++ b/bot.py @@ -189,6 +189,13 @@ class MyBot(commands.Bot): is_transient = isinstance(e, disnake.HTTPException) and e.status in [500, 502, 503, 504] if not isinstance(e, disnake.HTTPException): is_transient = True + # 403 with code 50013 = Missing Permissions - don't retry + if isinstance(e, disnake.HTTPException) and e.status == 403: + error_code = getattr(e, 'code', None) + # 50013 = Missing Permissions, 20023 = Cannot modify a role higher than bot's highest role + if error_code in (50013, 20023): + kuby_logger.warning(f"Missing Manage Roles permission to restore safe roles for {member} in {member.guild.name} - please ensure the bot has the Manage Roles permission") + break if is_transient and i < retries - 1: await asyncio.sleep((i + 1) * 2) continue diff --git a/commandes/bug_report.py b/commandes/bug_report.py index bab31e3..e319851 100644 --- a/commandes/bug_report.py +++ b/commandes/bug_report.py @@ -323,11 +323,10 @@ class BugReport(commands.Cog): f"**{current_labels_str}** pour l'issue #{issue_iid} ({issue_title})." ) except (disnake.Forbidden, disnake.HTTPException) as e: - if isinstance(e, disnake.Forbidden) or ( - isinstance(e, disnake.HTTPException) and e.code == 50007 - ): + error_code = getattr(e, 'code', None) + if isinstance(e, disnake.Forbidden) or error_code == 50007: kuby_logger.warning( - f"Impossible d'envoyer un MP à {user} ({user.id}) - MPs désactivés (Code: {getattr(e, 'code', 'Unknown')})" + f"Impossible d'envoyer un MP à {user} ({user.id}) - MPs désactivés (Code: {error_code})" ) if dev and dev.id != user.id: await dev.send( diff --git a/src/advanced_logger.py b/src/advanced_logger.py index f4cbfd5..9c65f39 100755 --- a/src/advanced_logger.py +++ b/src/advanced_logger.py @@ -123,22 +123,25 @@ class AdvancedLogger: try: logs = json.loads(content) except json.JSONDecodeError: - # Fallback: try to strip brackets and commas - content_clean = content.strip('[]').strip() - # This is getting complex, let's just try line-by-line fallback + # File is corrupt or semi-corrupt, try line-by-line pass - # If not a list or failed list parse, try NDJSON line-by-line - if not logs: - for line in content.splitlines(): - line = line.strip() - if not line: continue - # Strip trailing/leading commas in case of semi-corrupt legacy conversion - line = line.strip(',') - try: - logs.append(json.loads(line)) - except json.JSONDecodeError: - continue # Skip corrupt lines + # Try NDJSON line-by-line (handles both legacy and current format) + lines = content.splitlines() + for line in lines: + line = line.strip() + if not line: + continue + # Strip trailing/leading commas in case of semi-corrupt lines + line = line.strip(',') + if not line: + continue + try: + parsed = json.loads(line) + if isinstance(parsed, dict): + logs.append(parsed) + except json.JSONDecodeError: + continue # Skip corrupt lines # Guard against empty logs list after parsing if not logs: