mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
fix: keep Discord startup alive on command quota (#8061)
* fix: keep Discord startup alive on command quota * Update discord_platform_adapter.py --------- Co-authored-by: Weilong Liao <37870767+Soulter@users.noreply.github.com>
This commit is contained in:
@@ -427,8 +427,22 @@ class DiscordPlatformAdapter(Platform):
|
||||
|
||||
# 使用 Pycord 的方法同步指令
|
||||
# 注意:这可能需要一些时间,并且有频率限制
|
||||
await self.client.sync_commands()
|
||||
logger.info("[Discord] Command synchronization completed.")
|
||||
try:
|
||||
await self.client.sync_commands()
|
||||
logger.info("[Discord] Command synchronization completed.")
|
||||
except discord.HTTPException as e:
|
||||
if self._is_daily_command_quota_error(e):
|
||||
logger.warning(
|
||||
"[Discord] Daily application command create quota reached "
|
||||
"(30034); command sync skipped. Existing commands should "
|
||||
"continue to work until the quota resets.",
|
||||
)
|
||||
return
|
||||
logger.warning(f"[Discord] Sync commands failed: {e}")
|
||||
|
||||
@staticmethod
|
||||
def _is_daily_command_quota_error(error: discord.HTTPException) -> bool:
|
||||
return getattr(error, "code", None) == 30034
|
||||
|
||||
def _create_dynamic_callback(self, cmd_name: str):
|
||||
"""为每个指令动态创建一个异步回调函数"""
|
||||
|
||||
71
tests/test_discord_command_sync.py
Normal file
71
tests/test_discord_command_sync.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import asyncio
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.fixtures.mocks.discord import (
|
||||
MockDiscordBuilder,
|
||||
mock_discord_modules, # noqa: F401
|
||||
)
|
||||
|
||||
|
||||
class DiscordSyncError(Exception):
|
||||
def __init__(self, message: str, code: int | None = None) -> None:
|
||||
super().__init__(message)
|
||||
self.code = code
|
||||
|
||||
|
||||
def _build_adapter(monkeypatch: pytest.MonkeyPatch):
|
||||
from astrbot.core.platform.sources.discord import discord_platform_adapter
|
||||
from astrbot.core.platform.sources.discord.discord_platform_adapter import (
|
||||
DiscordPlatformAdapter,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(discord_platform_adapter, "star_handlers_registry", [])
|
||||
monkeypatch.setattr(
|
||||
discord_platform_adapter.discord,
|
||||
"HTTPException",
|
||||
DiscordSyncError,
|
||||
raising=False,
|
||||
)
|
||||
|
||||
adapter = DiscordPlatformAdapter(
|
||||
{"discord_command_register": True},
|
||||
{},
|
||||
asyncio.Queue(),
|
||||
)
|
||||
adapter.client = MockDiscordBuilder.create_client()
|
||||
return adapter
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_discord_command_sync_ignores_daily_quota(monkeypatch):
|
||||
from astrbot.core.platform.sources.discord import discord_platform_adapter
|
||||
|
||||
adapter = _build_adapter(monkeypatch)
|
||||
warning = Mock()
|
||||
monkeypatch.setattr(discord_platform_adapter.logger, "warning", warning)
|
||||
adapter.client.sync_commands.side_effect = DiscordSyncError(
|
||||
"Max number of daily application command creates reached",
|
||||
code=30034,
|
||||
)
|
||||
|
||||
await adapter._collect_and_register_commands()
|
||||
|
||||
adapter.client.sync_commands.assert_awaited_once()
|
||||
warning.assert_called_once()
|
||||
assert "30034" in warning.call_args.args[0]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_discord_command_sync_keeps_other_errors_fatal(monkeypatch):
|
||||
adapter = _build_adapter(monkeypatch)
|
||||
adapter.client.sync_commands.side_effect = DiscordSyncError(
|
||||
"Missing Access",
|
||||
code=50001,
|
||||
)
|
||||
|
||||
with pytest.raises(DiscordSyncError):
|
||||
await adapter._collect_and_register_commands()
|
||||
|
||||
adapter.client.sync_commands.assert_awaited_once()
|
||||
Reference in New Issue
Block a user