MenuDocs / erela.js

An easy-to-use Lavalink client for NodeJS.
Apache License 2.0
193 stars 80 forks source link

Bot gets disconnected from the player websocket with error 'Internal Error.' #145

Open DelxHQ opened 2 years ago

DelxHQ commented 2 years ago

I am completely unsure if this is an erela issue at all but I am experiencing an issue where music would just stop playing randomly. I get no errors or anything whenever this happens. Lavalink still sends events and still play's music according to the logs, though I think my bot just stops sending voice data to Discord.

The only way to have it send data again, is to destroy the player and create it again.

parnavh commented 2 years ago

It happens with me when I server deafen or mute the bot, although pausing and playing the bot sometimes fixes it

Misly16 commented 2 years ago

Can reproduce this when I server deafen/mute the bot

viztea commented 2 years ago

The best way of handling this is to pause/resume depending on the value of the mute field inside the VOICE_STATE_UPDATE data. As for server deafening this is probably an issue with erela.js, I'll see what I can do :ok_hand:

iwa commented 2 years ago

i did manual handling for server mute and server deafen to pause and resume the music, but it still happens to me :/ so it might be something else idk also lil tip, try to also handle pause/resume whenever the voice channel is updated, cause if someone changes the region of the channel for whatever reason, it'll also put the bot in this weird stopped-music state

txj-xyz commented 2 years ago

Just do something like this for both serverMute and serverDeafen for the <Client>#VoiceStateUpdate event

if (newState.serverMute == true && oldState.serverMute == false && oldState.member.id == client.user.id)
  return player.pause(true);
if (newState.serverMute == false && oldState.serverMute == true && oldState.member.id == client.user.id)
  return player.pause(false);
DelxHQ commented 2 years ago

I believe this issue is due to something closing the websocket to the player. I've been logging the socketClosed event and have been getting error codes from it, and I mean a lot of errors.

DelxHQ commented 2 years ago

Also note that my issue isn't to do with any of the comments above. My issue happens completely randomly without ANY interaction with the bot.

DelxHQ commented 2 years ago

I believe this issue is due to something closing the websocket to the player. I've been logging the socketClosed event and have been getting error codes from it, and I mean a lot of errors.

Can confirm it's the websocket being killed with code 4000 and reason being Internal Error.

iwa commented 2 years ago

alright so i've been doing some testing lately, and it seems that I can no longer run into this issue

I'm now using the voice-packet-improvements branch, and no issue so far It has been running locally for hours now, and with logging socketClosed enabled (no logs generated from it so far)

config:

seems that the changes done in #142 are working great so far

edit: i'm gonna test it for a few hours on my server running debian 11 and lavalink through docker, will post an update here to keep y'all in touch

viztea commented 2 years ago

Please test the new build branch, I've merged #142.

iwa commented 2 years ago

alright so, feedback few days later, my test has been a success even on my server (debian 11, lavalink through docker), no issue so far, and no errors from socketClosed, so #142 seems to really have fixed this issue

if you run into this issue, before posting, try to implement automatic play/pause on : server mute, server deafen, voice channel update, VC kick

sharing with y'all my code for that in TS, not sure its optimal tho:

Bot.on('voiceStateUpdate', async (oldState, newState) => {
    let channel = oldState.channel;
    if (!channel) return; // not parsing when the bot is connecting to a VC

    // If the bot is disconnected from a VC, destroys the player
    if (oldState.id === Bot.user.id && newState.id === Bot.user.id) {
        if (!newState.channel) {
            let player = Bot.music.players.get(oldState.guild.id);

            if (player)
                player.destroy();
        }
    }

    // If the bot is server muted, or server demuted, then pause / resume the music
    // Thanks @txj-xyz for the code
    if (newState.serverMute == true && oldState.serverMute == false && oldState.member.id == Bot.user.id) {
        let player = Bot.music.players.get(oldState.guild.id);
        player.pause(true);
        return;
    }

    if (newState.serverMute == false && oldState.serverMute == true && oldState.member.id == Bot.user.id) {
        let player = Bot.music.players.get(oldState.guild.id);
        player.pause(false);
        return;
    }

    // NOTE: not parsing server deafen here but it seems to be working without it, tho my bot is always self-deafen so it may break if not?
});
// VC Region Update
Bot.on('channelUpdate', async (oldChannel: VoiceChannel, newChannel: VoiceChannel) => {
    if (oldChannel.type === 'GUILD_VOICE' && newChannel.type === 'GUILD_VOICE') {
        let player = Bot.music.players.get(newChannel.guild.id);

        if (player) {
            if (player.voiceChannel === newChannel.id) {
                if (player.playing && !player.paused) {
                    player.pause(true);
                    setTimeout(() => {
                        player.pause(false);
                    }, 500); // Arbitrary cooldown, 0.5s seems to be working fine on my server but you might change this to a higher value if you're experiencing lag (haven't found a better way to do it yet)
                }
            }
        }
    }
});
viztea commented 2 years ago

Awesome, if everyone else reports the same thing I'll close this issue 👌🏼

DelxHQ commented 2 years ago

No errors reported so far either here too however there are still some issues with moving the bot into another voice channel. Get a socketClosed event telling me Session cannot be resumed. Am I suppose to handle this or is erela suppose to handle it?

viztea commented 2 years ago

@DelxHQ I'll look into it, thanks 👌🏼

viztea commented 2 years ago

@DelxHQ Please try using the latest build branch, it adds better voice state handling so it may fix your issue.

viztea commented 2 years ago

@txj-xyz @DelxHQ any updates?

DelxHQ commented 2 years ago

It happens less, though the same issue still occurs. Happens multiple players too it seems.

txj-xyz commented 2 years ago

Mine seems fine so far after 13hrs, still happens after about 2 days or so.

DelxHQ commented 2 years ago

It happens less, though the same issue still occurs. Happens multiple players too it seems.

Maybe I was wrong here. I've noticed it happen more and more as the bot stays online longer.

DelxHQ commented 2 years ago

Also moving the bot into a different channel still doesn't work. Just kills the websocket.

viztea commented 2 years ago

Unfortunate. If you or anyone else has any ideas feel free to PR/comment on this issue, I don't use erela.js and don't plan on doing so.

DelxHQ commented 2 years ago

This issue could potentially be fixed by Lavalink. I've updated lavalink to the latest commit from main and have not noticed any Internal Error errors ever since. Will keep this issue open for another few days to see just in case.

EDIT: still broken :(

DelxHQ commented 2 years ago

Seems to be fixed in commit a43298f

viztea commented 2 years ago

Interesting

Tomato6966 commented 2 years ago

Has nothing to do with undici

Has nothing much to do with lavalink

Its connection instability.

Lavalink controls the voice states.

If lavalink looses connection players might get destroyed when reciving the connection again.

The same applies to when erela js looses connection to lavalink. Which now happens more regularly from undici then it did with petitio