serenity-rs/songbird

`join` method returns Err but connecting to voice channel is successful

hexium310 opened this issue · 7 comments

Songbird version:
next(4fe2378)

Rust version (rustc -V):
rustc 1.70.0 (90c541806 2023-05-31)

Serenity/Twilight version:
next(serenity-rs/serenity@0c12aa8)

Output of ffmpeg -version, yt-dlp --version (if relevant):
...

Description:
Running a code after calling the esongbird::Songbird::join method is delayed. I checked that connecting to a voice channel was successful but the join return value was Err below.

failed to join voice channel: establishing connection failed

I tried the join method in the current branch, so connecting was successful and it returned Ok.

Steps to reproduce:

  1. Apply the following patch to examples/serenity/voice/src/main.rs
diff --git a/examples/serenity/voice/src/main.rs b/examples/serenity/voice/src/main.rs
index 8e4377b..be5c5f0 100644
--- a/examples/serenity/voice/src/main.rs
+++ b/examples/serenity/voice/src/main.rs
@@ -160,11 +160,18 @@ async fn join(ctx: &Context, msg: &Message) -> CommandResult {
         .expect("Songbird Voice client placed in at initialisation.")
         .clone();
 
-    if let Ok(handler_lock) = manager.join(guild_id, connect_to).await {
-        // Attach an event handler to see notifications of all track errors.
-        let mut handler = handler_lock.lock().await;
-        handler.add_global_event(TrackEvent::Error.into(), TrackErrorNotifier);
-    }
+    match manager.join(guild_id, connect_to).await {
+        Ok(handler_lock) => {
+            // Attach an event handler to see notifications of all track errors.
+            let mut handler = handler_lock.lock().await;
+            handler.add_global_event(TrackEvent::Error.into(), TrackErrorNotifier);
+        },
+        Err(why) => {
+            println!("{why}");
+        },
+    };
+
+    println!("Joined!");
 
     Ok(())
 }
  1. Execute cargo run in the examples/serenity/voice directory
  2. Join a voice channel and send ~join

Expected:
A bot connects to a voice channel and only Joined! would immediately be printed on a console.

Actual:
A bot connects a voice channel but failed to join voice channel: establishing connection failed and Joined! is printed on a console a few seconds later.

My best guess is that you're missing some intents, so the request is timing out on your side.

I tried running the example with let intents = GatewayIntents::all() in the main function, but it didn't resolve the issue.

Additional environment (OS): MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports) (Intel-based)
This issue isn't reproduced on Docker.

The detailed error with {why:?} is below:

Driver(Io(Os { code: 22, kind: InvalidInput, message: "Invalid argument" }))

I tried debugging with println!() and found that the point where the above error occurs is L115 in driver/connection.mod.rs:

socket.set_recv_buffer_size(0)?;

let udp = if cfg!(feature = "receive") {
udp
} else {
let socket = Socket::from(udp.into_std()?);
socket.set_recv_buffer_size(0)?;
UdpSocket::from_std(socket.into())?
};

I tentatively use the receive feature according to the condition above, and this issue is resolved.

Excellent debugging work there, I didn't expect MacOS would flake out in that way. This should be trivial to special-case; let me know if the next commit works.

It works with this commit on Mac!

Fantastic, closing for now then. Thanks for the input!