Skip to content

Shut down cleanly

When you stop the bot, it should leave its voice channels and log out instead of vanishing mid-song. In this guide you replace the quick start’s SIGINT listener with a shutdown that handles both stop signals and reports every failure.

In index.ts, delete the process.once("SIGINT", ...) block and add this in its place:

index.ts
let shutdownPromise: Promise<void> | undefined;
function shutdown(): Promise<void> {
shutdownPromise ??= (async () => {
const errors: unknown[] = [];
try {
await distube.dispose();
} catch (error) {
errors.push(error);
}
try {
await client.destroy();
} catch (error) {
errors.push(error);
}
if (errors.length > 0) throw new AggregateError(errors, "Shutdown failed");
})();
return shutdownPromise;
}
for (const signal of ["SIGINT", "SIGTERM"] as const) {
process.once(signal, () => {
shutdown().catch(error => console.error("Shutdown failed", error));
});
}

distube.dispose() does three things in order:

  1. It deletes every queue. Each one emits queue.deleted with the reason shutdown.
  2. It leaves every voice channel. Each voice emits voice.disconnected.
  3. It disposes the plugins, in the reverse of the order you listed them.

If a step fails, dispose still runs the rest and then rejects with one DisTubeError. Its cause is an AggregateError holding every failure. Calling dispose again returns the same promise.

The function destroys the Discord client after dispose, because leaving a voice channel needs the gateway connection. It destroys the client even when dispose fails, and then throws both failures together.

Ctrl+C in a terminal sends SIGINT. Docker, systemd and most process managers send SIGTERM to stop the bot. Both signals share one shutdownPromise, so the cleanup runs once even when both arrive.

process.once handles each signal only the first time. If cleanup hangs, a second Ctrl+C reaches Node’s default handler and exits the process at once.

Your bot now plays, queues, announces, filters and cleans up after itself. That is the end of the guide.

Popular topics covers questions that do not fit one bot: the FAQ, short sound clips, playing direct links and sizing the thread pool. The reference lists every option, queue method, voice setting, event and error code.