Skip to content
This repository was archived by the owner on Aug 28, 2019. It is now read-only.

Commit 47ca295

Browse files
committed
Change stderr prints to use the logging module instead
1 parent 49e6835 commit 47ca295

File tree

6 files changed

+38
-29
lines changed

6 files changed

+38
-29
lines changed

discord/app_commands/tree.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@
2323
"""
2424

2525
from __future__ import annotations
26+
import logging
2627
import inspect
27-
import sys
28-
import traceback
2928

3029
from typing import (
3130
Any,
@@ -79,6 +78,7 @@
7978

8079
ClientT = TypeVar('ClientT', bound='Client')
8180

81+
_log = logging.getLogger(__name__)
8282

8383
def _retrieve_guild_ids(
8484
command: Any, guild: Optional[Snowflake] = MISSING, guilds: Sequence[Snowflake] = MISSING
@@ -775,8 +775,8 @@ async def on_error(self, interaction: Interaction, error: AppCommandError) -> No
775775
776776
A callback that is called when any command raises an :exc:`AppCommandError`.
777777
778-
The default implementation prints the traceback to stderr if the command does
779-
not have any error handlers attached to it.
778+
The default implementation logs the exception using the library logger
779+
if the command does not have any error handlers attached to it.
780780
781781
To get the command that failed, :attr:`discord.Interaction.command` should
782782
be used.
@@ -794,11 +794,9 @@ async def on_error(self, interaction: Interaction, error: AppCommandError) -> No
794794
if command._has_any_error_handlers():
795795
return
796796

797-
print(f'Ignoring exception in command {command.name!r}:', file=sys.stderr)
797+
_log.error('Ignoring exception in command %r', command.name, exc_info=error)
798798
else:
799-
print(f'Ignoring exception in command tree:', file=sys.stderr)
800-
801-
traceback.print_exception(error.__class__, error, error.__traceback__, file=sys.stderr)
799+
_log.error('Ignoring exception in command tree', exc_info=error)
802800

803801
def error(self, coro: ErrorFunc) -> ErrorFunc:
804802
"""A decorator that registers a coroutine as a local error handler.

discord/client.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import logging
3030
import sys
3131
import os
32-
import traceback
3332
from typing import (
3433
Any,
3534
AsyncIterator,
@@ -519,16 +518,16 @@ async def on_error(self, event_method: str, /, *args: Any, **kwargs: Any) -> Non
519518
520519
The default error handler provided by the client.
521520
522-
By default this prints to :data:`sys.stderr` however it could be
521+
By default this logs to the library logger however it could be
523522
overridden to have a different implementation.
524523
Check :func:`~discord.on_error` for more details.
525524
526525
.. versionchanged:: 2.0
527526
528-
``event_method`` parameter is now positional-only.
527+
``event_method`` parameter is now positional-only
528+
and instead of writing to ``sys.stderr`` it logs instead.
529529
"""
530-
print(f'Ignoring exception in {event_method}', file=sys.stderr)
531-
traceback.print_exc()
530+
_log.exception('Ignoring exception in %s', event_method)
532531

533532
# hooks
534533

discord/ext/commands/bot.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import inspect
3232
import importlib.util
3333
import sys
34-
import traceback
34+
import logging
3535
import types
3636
from typing import (
3737
Any,
@@ -95,6 +95,7 @@
9595
T = TypeVar('T')
9696
CFT = TypeVar('CFT', bound='CoroFunc')
9797

98+
_log = logging.getLogger(__name__)
9899

99100
def when_mentioned(bot: _Bot, msg: Message, /) -> List[str]:
100101
"""A callable that implements a command prefix equivalent to being mentioned.
@@ -304,14 +305,15 @@ async def on_command_error(self, context: Context[BotT], exception: errors.Comma
304305
305306
The default command error handler provided by the bot.
306307
307-
By default this prints to :data:`sys.stderr` however it could be
308+
By default this logs to the library logger, however it could be
308309
overridden to have a different implementation.
309310
310311
This only fires if you do not specify any listeners for command error.
311312
312313
.. versionchanged:: 2.0
313314
314315
``context`` and ``exception`` parameters are now positional-only.
316+
Instead of writing to ``sys.stderr`` this now uses the library logger.
315317
"""
316318
if self.extra_events.get('on_command_error', None):
317319
return
@@ -324,8 +326,7 @@ async def on_command_error(self, context: Context[BotT], exception: errors.Comma
324326
if cog and cog.has_error_handler():
325327
return
326328

327-
print(f'Ignoring exception in command {context.command}:', file=sys.stderr)
328-
traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)
329+
_log.error('Ignoring exception in command %s', command, exc_info=exception)
329330

330331
# global check registration
331332

discord/ext/tasks/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242
import aiohttp
4343
import discord
4444
import inspect
45-
import sys
46-
import traceback
4745

4846
from collections.abc import Sequence
4947
from discord.backoff import ExponentialBackoff
@@ -536,8 +534,7 @@ def is_running(self) -> bool:
536534

537535
async def _error(self, *args: Any) -> None:
538536
exception: Exception = args[-1]
539-
print(f'Unhandled exception in internal background task {self.coro.__name__!r}.', file=sys.stderr)
540-
traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr)
537+
_log.error('Unhandled exception in internal background task %r.', self.coro.__name__, exc_info=exception)
541538

542539
def before_loop(self, coro: FT) -> FT:
543540
"""A decorator that registers a coroutine to be called before the loop starts running.
@@ -600,11 +597,15 @@ def error(self, coro: ET) -> ET:
600597
601598
The coroutine must take only one argument the exception raised (except ``self`` in a class context).
602599
603-
By default this prints to :data:`sys.stderr` however it could be
600+
By default this logs to the library logger however it could be
604601
overridden to have a different implementation.
605602
606603
.. versionadded:: 1.4
607604
605+
.. versionchanged:: 2.0
606+
607+
Instead of writing to ``sys.stderr``, the library's logger is used.
608+
608609
Parameters
609610
------------
610611
coro: :ref:`coroutine <coroutine>`

docs/api.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ overriding the specific events. For example: ::
195195

196196

197197
If an event handler raises an exception, :func:`on_error` will be called
198-
to handle it, which defaults to print a traceback and ignoring the exception.
198+
to handle it, which defaults to logging the traceback and ignoring the exception.
199199

200200
.. warning::
201201

@@ -350,19 +350,14 @@ Debug
350350
.. function:: on_error(event, *args, **kwargs)
351351

352352
Usually when an event raises an uncaught exception, a traceback is
353-
printed to stderr and the exception is ignored. If you want to
353+
logged to stderr and the exception is ignored. If you want to
354354
change this behaviour and handle the exception for whatever reason
355355
yourself, this event can be overridden. Which, when done, will
356356
suppress the default action of printing the traceback.
357357

358358
The information of the exception raised and the exception itself can
359359
be retrieved with a standard call to :func:`sys.exc_info`.
360360

361-
If you want exception to propagate out of the :class:`Client` class
362-
you can define an ``on_error`` handler consisting of a single empty
363-
:ref:`raise statement <py:raise>`. Exceptions raised by ``on_error`` will not be
364-
handled in any way by :class:`Client`.
365-
366361
.. note::
367362

368363
``on_error`` will only be dispatched to :meth:`Client.event`.
@@ -371,6 +366,10 @@ Debug
371366
:ref:`ext_commands_api_bot` listeners such as
372367
:meth:`~ext.commands.Bot.listen` or :meth:`~ext.commands.Cog.listener`.
373368

369+
.. versionchanged:: 2.0
370+
371+
The traceback is now logged rather than printed.
372+
374373
:param event: The name of the event that raised the exception.
375374
:type event: :class:`str`
376375

docs/migrating.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,17 @@ The following methods have been changed:
933933
- :meth:`Webhook.send`
934934
- :meth:`abc.GuildChannel.set_permissions`
935935

936+
Logging Changes
937+
----------------
938+
939+
The library now provides a default logging configuration if using :meth:`Client.run`. To disable it, pass ``None`` to the ``log_handler`` keyword parameter. Since the library now provides a default logging configuration, certain methods were changed to no longer print to :data:`sys.stderr` but use the logger instead:
940+
941+
- :meth:`Client.on_error`
942+
- :meth:`discord.ext.tasks.Loop.error`
943+
- :meth:`discord.ext.commands.Bot.on_command_error`
944+
945+
For more information, check :doc:`logging`.
946+
936947
Removal of ``StoreChannel``
937948
-----------------------------
938949

0 commit comments

Comments
 (0)