yuntongzhang / test

MIT License
0 stars 2 forks source link

VoiceClient.play() doesn't pass FFMPEG error to 'after' function. #6

Open yuntongzhang opened 2 months ago

yuntongzhang commented 2 months ago

Summary

VoiceClient.play() doesn't pass FFMPEG error to 'after' function.

Reproduction Steps

I know from https://github.com/Rapptz/discord.py/issues/5131 that the session invalidation error is not a Discord.py error, however, the VoiceClient's play() function does not seem to be capturing and passing the FFMPEG error into my provided after function. I would like to notify when this error happens, so capturing this error would be very helpful. It also appears that Discord.py wrongly states that FFMPEG exited successfully, even when it exits with code 1, which by definition, is not successful.

Here is my current code and log results: Code:

def sync_playback_error(error: Exception = None):
    async def playback_error(error: Exception = None):
        has_error: bool = error != None
        if has_error:
            print('Sending error to chat...')
            await ctx.message.channel.send('A playback error has caused the audio stream to stop.')
        else:
            print('No error in playback!')
    print('Starting async callback...')
    asyncio.run_coroutine_threadsafe(playback_error(error), self.bot.loop)

# Attempt to play ffmpeg source
vc.play(ffmpeg_src, after=sync_playback_error)

Logs:

[tls @ 0x5632a384eb80] Error in the pull function.
[matroska,webm @ 0x5632a384a600] Read error
[tls @ 0x5632a384eb80] The specified session has been invalidated for some reason.
    Last message repeated 1 times
Starting async callback...
DEBUG:asyncio:Using selector: EpollSelector
No error in playback!
2024-06-15 16:58:28 INFO     discord.player ffmpeg process 2801802 successfully terminated with return code of 1.

Minimal Reproducible Code

No response

Expected Results

I expected the FFMPEG error to be passed to the after function

Actual Results

The error was not captured and passed to the after function

Intents

discord.Intents.default()

System Information

Python v3.10.12-final discord.py v2.3.2-final aiohttp v3.9.5 system info: Linux 5.15.0-112-generic https://github.com/Rapptz/discord.py/pull/122 SMP Thu May 23 07:48:21 UTC 2024

Checklist

Additional Context

No response

code-rover-bot[bot] commented 2 months ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

yuntongzhang commented 1 month ago

@acr-bot

yuntongzhang commented 1 month ago

@acr-bot sonnet

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Anthropic API key is missing. Please set it up in the repository.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

I could not generate a patch for this issue.

yuntongzhang commented 1 month ago

@acr-bot sonnet

code-rover-bot[bot] commented 1 month ago

Here is a potential patch for reference:

diff --git a/discord/player.py b/discord/player.py
index 5b2c99dc..7070838f 100644
--- a/discord/player.py
+++ b/discord/player.py
@@ -231,6 +231,8 @@ class FFmpegAudio(AudioSource):
         else:
             _log.info('ffmpeg process %s successfully terminated with return code of %s.', proc.pid, proc.returncode)

+        self._ffmpeg_return_code = proc.returncode
+
     def _pipe_writer(self, source: io.BufferedIOBase) -> None:
         while self._process:
             data = source.read(self.BLOCKSIZE)
@@ -737,7 +739,12 @@ class AudioPlayer(threading.Thread):
                 self._resumed.wait()
                 continue

-            data = self.source.read()
+            try:
+                data = self.source.read()
+            except Exception as e:
+                if isinstance(self.source, FFmpegAudio):
+                    raise ClientException(f"FFmpeg error: {str(e)}") from e
+                raise

             if not data:
                 self.stop()
@@ -769,6 +776,9 @@ class AudioPlayer(threading.Thread):
     def run(self) -> None:
         try:
             self._do_run()
+        except ClientException as exc:
+            self._current_error = exc
+            self.stop()
         except Exception as exc:
             self._current_error = exc
             self.stop()
diff --git a/discord/voice_client.py b/discord/voice_client.py
index 3e1c6a5f..b89f407f 100644
--- a/discord/voice_client.py
+++ b/discord/voice_client.py
@@ -493,7 +493,14 @@ class VoiceClient(VoiceProtocol):
                 signal_type=signal_type,
             )

-        self._player = AudioPlayer(source, self, after=after)
+        def _after_callback(error):
+            if after:
+                if error:
+                    after(error)
+                else:
+                    after(None)
+
+        self._player = AudioPlayer(source, self, after=_after_callback)
         self._player.start()

     def is_playing(self) -> bool:

This run costs 0.27 USD.

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr

yuntongzhang commented 1 month ago

@acr-bot open-pr