dgvoice icon indicating copy to clipboard operation
dgvoice copied to clipboard

Occasional crash when attempting to join VC

Open colecrouter opened this issue 3 years ago • 3 comments

Pretty straight forward. When I do:

vc, err = s.ChannelVoiceJoin(e.GuildID, e.ChannelID, false, false)

it sometimes crashes, seemingly randomly. Sometimes it happens a several times a day, sometimes not at all. This isn't my first time running into this issue; I originally ran this same bot in nodeJS but this same connection problem created an unrecoverable WASM crash. This makes me thing it's probably a fundamental issue, rather than a one specifically with this library. Here's the error:

2020/11/09 03:00:51 error: timeout waiting for voice

and sometimes:

dgVoice: timeout waiting for voice

Very strange. I've also tried using matryer/try to catch and repeat the process, but it doesn't seem to do anything different (probably running on a separate goroutine). Any idea how I might investigate this one?

colecrouter avatar Nov 09 '20 04:11 colecrouter

Hey @Mexican-Man when you say "crashes" do you mean your Go application actually crashes, panics, or otherwise dies?

Or just mean to say it doesn't actually connect to the Voice Channel? The error msg you're getting implies it never received the voice packet back from Discord which could be a network issue or a discord issue for sure - it could also be a bug in the library too but I haven't had many widespread reports so I'm leaning toward maybe some occasional Discord problem.

bwmarrin avatar Feb 25 '21 17:02 bwmarrin

It's been a hot minute since I've had to deal with this error, so I'll check again after work, but I was wrong about the source of the panic. Iirc it was playing the sound that was throwing the panic. Basically ChannelVoiceJoin is connecting, but doesn't return a valid connection.

I wasn't able to reliably catch the edge case, but I was able to bandaid it using a "is connected" variable. Then I would stop it from playing a sound if it was "connected". Then I would reset it back to true. Not much of a solution, but in my case it would sometimes not work once, but then keep working instead of crashing. I'll post some code later.

colecrouter avatar Feb 25 '21 21:02 colecrouter

Ok so I do this right before joining:

	if !isDone {
		vc.Disconnect()
		isDone = true
		return
	}
	isDone = false

where is done is just a global variable. This code is ran if it tries to play a sound, but it hasn't been "finished" yet. Notice how I'm forcibly setting isDone to true, which could trigger the crash if three things tried to play at the same time (I think?). Then I do this, which someone on here suggested doing, and it does seem to help, but not solve it:

	var vc *discordgo.VoiceConnection
	// Copied this from the internet, supposedly it stops that super annoying RANDOM CRASH ALL THE TIME GRRRR
	vc, err = s.ChannelVoiceJoin(e.GuildID, e.ChannelID, false, false)
	if err != nil {
		if _, ok := s.VoiceConnections[e.GuildID]; ok {
			vc = s.VoiceConnections[e.GuildID]
		} else {
			return
		}
	}
	if err != nil {
                // this never seems to happen.
		log.Fatalln("error connecting:", err)
		return
	}

Basically, it's just trying to join, and if it throws an error (I don't remember if it throws an error 100% of the time or not), it tries to set the current voice channel to desired channel manually. Lastly, I try to play the sound

dgvoice.PlayAudioFile(vc, "./sounds/"+e.UserID+".mp3", make(chan bool))

I spent lots of time trimming down unnecessary code, so I'm pretty sure this is all that's required to get where I am. This seems to stop it from crashing most of the time (like 99%). It's still pretty hacky; like I said, if it fails to play the sound, there's no warning or retry or anything, it just doesn't, then the rest of the code above attempts to catch that the next time.

I was completely wrong about it crashing on join, that was something else I had which was my fault.

colecrouter avatar Feb 26 '21 01:02 colecrouter