I’m working on creating a timer feature for my Discord bot but running into issues. When I try to execute the command, the bot stops responding completely.
Here’s my current code:
// Message handler
client.on('messageCreate', async msg => {
const user = msg.author;
const commandArgs = msg.content.slice(prefix.length).trim().split(/ +/);
const cmd = commandArgs.shift().toLowerCase();
// Timer variables
let timerStart = 0;
let timeLeft = 15;
// Timer command
if (cmd === 'countdown') {
while(timerStart <= 14) {
setTimeout(() => {
msg.channel.send(timeLeft);
timerStart++;
timeLeft--;
}, 1000);
}
}
});
The bot crashes when I run this command and I can’t figure out why. I think there’s something wrong with how I’m handling the loop and setTimeout together. Can someone explain what’s causing this problem and how to fix it? I’d also appreciate an explanation of why this approach doesn’t work as expected.
Thanks for any help!
The fundamental issue here is that your while loop executes synchronously and immediately schedules all setTimeout callbacks at once, rather than waiting for each timer to complete. This creates a race condition where timerStart and timeLeft variables get modified by multiple setTimeout callbacks simultaneously, leading to unpredictable behavior and potential memory issues. A cleaner approach would be using a recursive setTimeout pattern. Replace your while loop with a single function that calls itself after the delay. This ensures each countdown step completes before the next one begins. Something like creating a doCountdown() function that decrements your counter, sends the message, then calls setTimeout(doCountdown, 1000) if the timer hasn’t reached zero yet. This way you maintain proper timing control and avoid overwhelming the event loop with simultaneous callbacks.
I had this exact same problem when building my first Discord bot timer. The issue is that your while loop executes immediately without waiting for the setTimeout delays, so it creates 15 separate timers all at once instead of sequential countdown steps. What happens is the loop finishes instantly, scheduling all the setTimeout functions to run after 1 second simultaneously, which overwhelms your bot and causes the crash. The variables timerStart and timeLeft also get captured incorrectly due to closure issues. I solved this by switching to setInterval instead, which naturally handles the timing without needing a loop. Just store the interval ID so you can clear it when the countdown reaches zero. Much cleaner and prevents the bot from hanging or crashing.
u got an infinite loop, dude. the while loop runs right away and queues like 15 setTimeouts at once, which is too much for the bot. try setInterval or a single setTimeout that calls itself. then you’ll have proper 1 sec delays between messages.