From 839afce17890a03c0718d5ad76069b641da54034 Mon Sep 17 00:00:00 2001 From: Imayhaveborkedit Date: Wed, 20 Nov 2019 00:34:23 -0500 Subject: [PATCH] Print exception tracebacks in voice threads Errors occurring within `AudioSource.read()` and `after()` functions will now display their tracebacks as if they were unhandled exceptions. --- discord/player.py | 15 +++++++++++++-- discord/voice_client.py | 8 ++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/discord/player.py b/discord/player.py index 727584057..0b4c850da 100644 --- a/discord/player.py +++ b/discord/player.py @@ -25,6 +25,7 @@ DEALINGS IN THE SOFTWARE. """ import threading +import traceback import subprocess import audioop import asyncio @@ -32,6 +33,7 @@ import logging import shlex import time import json +import sys import re from .errors import ClientException @@ -602,11 +604,20 @@ class AudioPlayer(threading.Thread): self._call_after() def _call_after(self): + error = self._current_error + if self.after is not None: try: - self.after(self._current_error) - except Exception: + self.after(error) + except Exception as exc: log.exception('Calling the after function failed.') + exc.__context__ = error + traceback.print_exception(type(exc), exc, exc.__traceback__) + elif error: + msg = 'Exception in voice thread {}'.format(self.name) + log.exception(msg, exc_info=error) + print(msg, file=sys.stderr) + traceback.print_exception(type(error), error, error.__traceback__) def stop(self): self._end.set() diff --git a/discord/voice_client.py b/discord/voice_client.py index 639757437..f3729c9e6 100644 --- a/discord/voice_client.py +++ b/discord/voice_client.py @@ -338,7 +338,8 @@ class VoiceClient: or an error occurred. If an error happens while the audio player is running, the exception is - caught and the audio player is then stopped. + caught and the audio player is then stopped. If no after callback is + passed, any caught exception will be displayed as if it were raised. Parameters ----------- @@ -346,9 +347,8 @@ class VoiceClient: The audio source we're reading from. after: Callable[[:class:`Exception`], Any] The finalizer that is called after the stream is exhausted. - All exceptions it throws are silently discarded. This function - must have a single parameter, ``error``, that denotes an - optional exception that was raised during playing. + This function must have a single parameter, ``error``, that + denotes an optional exception that was raised during playing. Raises -------