From 9e02e50693fac71ad6af47c93fcef23b7acbb146 Mon Sep 17 00:00:00 2001 From: aki Date: Thu, 24 Apr 2025 02:50:17 +0800 Subject: [PATCH] fix(ShoukakuEvents.js): improve error handling during track playback and logging --- src/structures/ShoukakuEvents.js | 47 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/structures/ShoukakuEvents.js b/src/structures/ShoukakuEvents.js index 93a804b..6db9805 100644 --- a/src/structures/ShoukakuEvents.js +++ b/src/structures/ShoukakuEvents.js @@ -55,11 +55,19 @@ class MusicPlayer { // Play a track async play(track) { this.current = track; - - // Start playback - await this.connection.playTrack({ track: track.encoded }); - this.playing = true; - + logger.debug(`Attempting to play track: ${track.info.title} (${track.info.uri}) in guild ${this.guild}`); + try { + // Start playback + await this.connection.playTrack({ track: track.encoded }); + this.playing = true; + logger.debug(`playTrack called successfully for: ${track.info.title}`); + } catch (playError) { + logger.error(`Error calling playTrack for ${track.info.title}: ${playError.message}`); + console.error(playError); // Log full error object + this.playing = false; + this.current = null; + // Maybe try skipping? Or just log and let the 'end' event handle it if it fires. + } return this; }, @@ -116,8 +124,10 @@ class MusicPlayer { // Add a track to the queue or play it if nothing is playing async enqueue(track, immediate = false) { if (immediate || (!this.playing && !this.current)) { + logger.debug(`Enqueue: Playing immediately - ${track.info.title}`); await this.play(track); } else { + logger.debug(`Enqueue: Adding to queue - ${track.info.title}`); this.queue.push(track); } return this; @@ -176,14 +186,15 @@ class MusicPlayer { }); connection.on('exception', (error) => { - logger.error(`Track error in guild ${player.guild}: ${error.message}`); + logger.error(`Track exception in guild ${player.guild}: ${error.message || 'Unknown error'}`); + console.error("Full track exception details:", error); // Log the full error object const channel = this.client.channels.cache.get(player.textChannel); if (channel) { - channel.send(`An error occurred while trying to play: ${player.current?.info?.title || 'the track'}. - Details: ${error.message || 'Unknown error'}`).catch(e => - logger.error(`Failed to send trackError message: ${e.message}`) + channel.send(`An error occurred during playback: ${error.message || 'Unknown error'}`).catch(e => + logger.error(`Failed to send trackException message: ${e.message}`) ); } + // Attempt to skip to the next track on exception player.skip(); }); @@ -208,28 +219,18 @@ class MusicPlayer { /** * Search for tracks using Shoukaku * @param {Object} options Options for the search - * @param {string} options.query The search query + * @param {string} options.identifier The pre-constructed search identifier (e.g., 'ytsearch:query', 'scsearch:query', or a URL) * @param {string} options.requester The user who requested the track * @returns {Promise} Array of track objects */ - async search({ query, requester }) { + async search({ identifier, requester }) { // Accept identifier directly // Get the first available node const node = this.client.shoukaku.options.nodeResolver(this.client.shoukaku.nodes); if (!node) throw new Error('No available Lavalink nodes!'); try { - // Determine search type and prepare the identifier string - let identifier; - if (query.startsWith('http')) { - // Direct URL - identifier = query; - } else { - // Search with prefix (Lavalink handles ytsearch/ytmsearch automatically with the plugin) - // identifier = `ytsearch:${query}`; // Prefix might not be needed with the plugin, let Lavalink decide - identifier = query; // Pass the raw query for non-URLs - } - - // Perform the search using the identifier string + // Perform the search using the provided identifier string + logger.debug(`Performing search with identifier: ${identifier}`); const result = await node.rest.resolve(identifier); if (!result || result.loadType === 'error' || result.loadType === 'empty') { // Log the identifier for debugging if search fails