首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >默认情况下,discord.py隐藏哪些错误?

默认情况下,discord.py隐藏哪些错误?
EN

Stack Overflow用户
提问于 2022-07-15 16:34:10
回答 1查看 339关注 0票数 0

我在许多关于堆栈溢出的文章中提到过,如果没有配置日志记录,默认情况下discord.py会“隐藏错误”。在文档中,有人提到:

强烈建议配置日志模块,因为如果不设置,则不会输出错误或警告。重点雷

但是,在discord.py 1.7.3中,我观察到错误被输出到控制台。运行以下代码片段:

代码语言:javascript
运行
复制
import discord

client = discord.Client(intents=discord.Intents.all())


@client.event
async def on_ready():
    raise ValueError

client.run(TOKEN)

正确地引发ValueError -错误不会被吞没。

在discord.py 2.0中,已经设置了日志记录,输出(具有相同的代码片段)就证明了这一点:

代码语言:javascript
运行
复制
[2022-07-15 12:28:40] [INFO    ] discord.client: logging in using static token
[2022-07-15 12:28:41] [INFO    ] discord.gateway: Shard ID None has sent the IDENTIFY payload.
[2022-07-15 12:28:41] [INFO    ] discord.gateway: Shard ID None has connected to Gateway (Session ID: ...).
[2022-07-15 12:28:43] [ERROR   ] discord.client: Ignoring exception in on_ready
# ^-----------------^ These lines are all from the logging module
Traceback (most recent call last):
  File "C:\Users\TheFu\PycharmProjects\mcve2.0\venv\lib\site-packages\discord\client.py", line 456, in _run_event
    await coro(*args, **kwargs)
  File "C:\Users\TheFu\PycharmProjects\mcve2.0\main.py", line 8, in on_ready
    raise ValueError
ValueError

那么,如果没有在discord.py 1.7.3中设置日志记录,那么为什么输出一个错误呢?在这个版本中会被哪些错误吞没?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-17 19:22:11

默认情况下,在1.7.3中,它完全绕过日志记录并直接打印到stderr (代码在这里):

代码语言:javascript
运行
复制
async def on_error(self, event_method, *args, **kwargs):
    print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
    traceback.print_exc()

然后调用on_error,类似于下面的这里

代码语言:javascript
运行
复制
    async def _run_event(self, coro, event_name, *args, **kwargs):
        try:
            await coro(*args, **kwargs)
        except asyncio.CancelledError:
            pass
        except Exception:
            try:
                await self.on_error(event_name, *args, **kwargs)
            except asyncio.CancelledError:
                pass

不管是否设置了日志记录,它都会这样做。

我用这个简化版本的机器人来测试它。注意,它在错误消息中包含了_run_event,这应该是上面代码中链接的相同的错误消息。

代码语言:javascript
运行
复制
import discord
from discord.ext import commands
import logging
import sys

LOGGING_ENABLE = True
if LOGGING_ENABLE:
    log = logging.getLogger()
    log.setLevel(logging.INFO)
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.INFO)
    handler.setFormatter(logging.Formatter('\033[0;36m%(asctime)s \033[0;32m%(levelname)s\033[0;0m %(message)s', '%Y%m%d %H:%M:%S'))
    log.addHandler(handler)

print(f'discord version {discord.__version__}')
intent = discord.Intents.all()
client = commands.Bot(command_prefix='sudo ', intents=intent)

@client.event
async def on_ready():
    print('logged in')
    print('raising exception!')
    raise ValueError()

print('starting client.run:')
client.run(...)

当日志记录是而不是设置时给出的

代码语言:javascript
运行
复制
discord version 1.7.3
starting client.run:
logged in
raising exception!
Ignoring exception in on_ready
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/discord/client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "/home/greateric/Documents/PYTHON/old-discordbot/bot_cut.py", line 14, in on_ready
    raise ValueError()
ValueError

并给出了日志记录设置的时间。

代码语言:javascript
运行
复制
discord version 1.7.3
starting client.run:
20220717 14:50:10 INFO logging in using static token
20220717 14:50:11 INFO Shard ID None has sent the IDENTIFY payload.
20220717 14:50:12 INFO Shard ID None has connected to Gateway: <a bunch of irrelevant stuff>.
logged in
raising exception!
Ignoring exception in on_ready
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/discord/client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "/home/greateric/Documents/PYTHON/old-discordbot/bot_cut.py", line 23, in on_ready
    raise ValueError()
ValueError
^C20220717 14:50:15 INFO Cleaning up tasks.
20220717 14:50:15 INFO Cleaning up after 1 tasks.
20220717 14:50:15 INFO All tasks finished cancelling.
20220717 14:50:15 INFO Closing the event loop.

在2.0中,在启用日志记录的情况下,它实际上“很好”地打印了错误。

代码语言:javascript
运行
复制
discord version 2.0.0a
20220717 14:53:09 WARNING PyNaCl is not installed, voice will NOT be supported
starting client.run:
2022-07-17 14:53:09 INFO     discord.client logging in using static token
20220717 14:53:09 INFO logging in using static token
2022-07-17 14:53:09 INFO     discord.gateway Shard ID None has sent the IDENTIFY payload.
20220717 14:53:09 INFO Shard ID None has sent the IDENTIFY payload.
2022-07-17 14:53:09 INFO     discord.gateway Shard ID None has connected to Gateway (Session ID: ...).
20220717 14:53:09 INFO Shard ID None has connected to Gateway (Session ID: ...).
logged in
raising exception!
2022-07-17 14:53:12 ERROR    discord.client Ignoring exception in on_ready
Traceback (most recent call last):
  File "/home/greateric/Documents/PYTHON/old-discordbot/venv/lib/python3.9/site-packages/discord/client.py", line 456, in _run_event
    await coro(*args, **kwargs)
  File "/home/greateric/Documents/PYTHON/old-discordbot/bot_cut.py", line 23, in on_ready
    raise ValueError()
ValueError
20220717 14:53:12 ERROR Ignoring exception in on_ready
Traceback (most recent call last):
  File "/home/greateric/Documents/PYTHON/old-discordbot/venv/lib/python3.9/site-packages/discord/client.py", line 456, in _run_event
    await coro(*args, **kwargs)
  File "/home/greateric/Documents/PYTHON/old-discordbot/bot_cut.py", line 23, in on_ready
    raise ValueError()
ValueError

(我不知道这里发生了什么,但我认为是两个伐木处理人员为了争夺对方而争吵。屏幕截图与颜色这里)

实际上,当我禁用日志记录时,会发生这样的情况:

代码语言:javascript
运行
复制
discord version 2.0.0a
starting client.run:
2022-07-17 14:56:40 INFO     discord.client logging in using static token
2022-07-17 14:56:40 INFO     discord.gateway Shard ID None has sent the IDENTIFY payload.
2022-07-17 14:56:40 INFO     discord.gateway Shard ID None has connected to Gateway (Session ID: 85657d0594417664850b2c03c2ca0d77).
logged in
raising exception!
2022-07-17 14:56:42 ERROR    discord.client Ignoring exception in on_ready
Traceback (most recent call last):
  File "/home/greateric/Documents/PYTHON/old-discordbot/venv/lib/python3.9/site-packages/discord/client.py", line 456, in _run_event
    await coro(*args, **kwargs)
  File "/home/greateric/Documents/PYTHON/old-discordbot/bot_cut.py", line 23, in on_ready
    raise ValueError()
ValueError

现在看来,discord.py正在制作自己的日志处理程序(独立于我上次创建的日志处理程序)。

代码是不同的。(代码段,来自提交52f3a3496bea13fefc08b38f9ed01641e565d0eb)

代码语言:javascript
运行
复制
async def on_error(self, event_method: str, /, *args: Any, **kwargs: Any) -> None:
        """|coro|
        The default error handler provided by the client.
        By default this logs to the library logger however it could be
        overridden to have a different implementation.
        Check :func:`~discord.on_error` for more details.
        .. versionchanged:: 2.0
            ``event_method`` parameter is now positional-only
            and instead of writing to ``sys.stderr`` it logs instead.
        """
        _log.exception('Ignoring exception in %s', event_method)

由于,记录器独立于您自己的设置记录器。

代码语言:javascript
运行
复制
_log = logging.getLogger(__name__)

它还在__init__.py中添加了一个处理程序。

代码语言:javascript
运行
复制
logging.getLogger(__name__).addHandler(logging.NullHandler())

以这两个文件为例:

a.py

代码语言:javascript
运行
复制
import logging
import sys

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.INFO)
handler.setFormatter(logging.Formatter('\033[0;36m%(asctime)s \033[0;32m%(levelname)s\033[0;0m %(message)s', '%Y%m%d %H:%M:%S'))
logging.getLogger(__name__).addHandler(handler)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

logger.info('hi from a.py')
print('done executing a.py')

b.py

代码语言:javascript
运行
复制
import logging
import a
import sys

LOGGING_ENABLE = True
if LOGGING_ENABLE:
    logger = logging.getLogger()
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.INFO)
    handler.setFormatter(logging.Formatter('\033[0;33mreminder that this is the formatter of b.py \033[0;36m%(asctime)s \033[0;32m%(levelname)s\033[0;0m %(message)s', '%Y%m%d %H:%M:%S'))
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)
    logger.info('hi from b.py')

print('just finished running b.py')

如果启用了LOGGING_ENABLE,这就是输出。这两个记录器完全相互独立(它们有不同的格式化程序)。

代码语言:javascript
运行
复制
20220717 15:10:49 INFO hi from a.py
done executing a.py
reminder that this is the formatter of b.py 20220717 15:10:49 INFO hi from b.py
just finished running b.py

b.py中没有记录器时,a.py的记录器仍然工作:

代码语言:javascript
运行
复制
20220717 15:11:19 INFO hi from a.py
done executing a.py
just finished running b.py

or的2.0记录器独立于代码的记录器或缺少一个记录器。不管您自己的记录器设置是什么,它自己的记录器总是会打印错误。

在任何版本中都不应该错误(除了非Exception错误,如KeyboardInterrupt之类的错误)。在2.0中,_run_event基本上是相同的:

代码语言:javascript
运行
复制
    async def _run_event(
        self,
        coro: Callable[..., Coroutine[Any, Any, Any]],
        event_name: str,
        *args: Any,
        **kwargs: Any,
    ) -> None:
        try:
            await coro(*args, **kwargs)
        except asyncio.CancelledError:
            pass
        except Exception:
            try:
                await self.on_error(event_name, *args, **kwargs)
            except asyncio.CancelledError:
                pass

如果有“没有错误”,这通常意味着它被故意忽略,例如,如果您覆盖错误处理程序。也可能是因为某些原因,您的终端忽略了stderr,这在我的另一个项目中发生过一次。

在1.7.3中,无论任何日志记录配置,这些错误都将被打印到stderr,而在2.0中,这些错误将使用不和谐的记录器记录。

当它说什么都不会输出到文档上时,它意味着额外的日志信息,比如logging in using static token信息。错误跟踪仍然直接打印到stderr。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72997136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档