diff --git a/bot.py b/bot.py index bacca3b..afa3d5b 100644 --- a/bot.py +++ b/bot.py @@ -365,6 +365,10 @@ class GravityBot(commands.Bot): if project_name in self.project_channels: return self.project_channels[project_name] + if not self.session_category: + logger.error(f"[CHANNEL] session_category is None β€” cannot get channel for project={project_name}") + return None + channel_name = self._make_channel_name(project_name) # 1. Check guild channel cache (NO API call β€” instant) @@ -405,6 +409,9 @@ class GravityBot(commands.Bot): except discord.errors.Forbidden: logger.error(f"No permission to create channel: {channel_name}") return None + except Exception as e: + logger.error(f"[CHANNEL] Failed to create channel #{channel_name}: {e}") + return None def _resolve_project(self, conversation_id: str) -> str: """Get project name for a conversation. Falls back to default.""" @@ -619,13 +626,18 @@ class GravityBot(commands.Bot): # Show compact auto-approved embed in Discord channel = await self._get_channel(project) if channel: - embed = discord.Embed( - title="πŸ€– μžλ™ 승인됨", - description=f"```\n{req.command[:500]}\n```", - color=discord.Color.green(), - ) - embed.set_footer(text=f"auto-approve | {req.request_id[:12]}") - await channel.send(embed=embed) + try: + embed = discord.Embed( + title="πŸ€– μžλ™ 승인됨", + description=f"```\n{req.command[:500]}\n```", + color=discord.Color.green(), + ) + embed.set_footer(text=f"auto-approve | {req.request_id[:12]}") + await channel.send(embed=embed) + except Exception as e: + logger.error(f"[AUTO-APPROVE] Discord send failed for {project}: {e}") + else: + logger.warning(f"[AUTO-APPROVE] No Discord channel for project={project} β€” notification skipped") logger.info(f"Auto-approved: {req.request_id[:12]} project={project} btn_idx={approve_btn_index}") phase1_processed += 1 continue @@ -655,6 +667,8 @@ class GravityBot(commands.Bot): self._sent_commands[req.request_id] = req.command await self._send_approval_request(channel, req) phase1_processed += 1 + else: + logger.warning(f"[APPROVAL] No Discord channel for project={project} β€” approval request skipped (rid={req.request_id[:12]})") # ── Single-pass: handle auto_resolved, expired, and MERGE in one glob ── phase2_processed = 0 @@ -894,7 +908,9 @@ class GravityBot(commands.Bot): if content or attached_files: channel = await self._get_channel(project) - if channel: + if not channel: + logger.warning(f"[SNAPSHOT] No Discord channel for project={project} β€” snapshot skipped (len={len(content)})") + elif channel: import io # ── Send attached files (from Extension's writeChatSnapshotWithFiles) ──