Search code examples
javascriptnode.jsdiscord.jslistenerspawn

Discord.js: The "listener" argument must be of type function. Returning undefined


I have this script that's supposed to create a Minecraft server using spawn(), and it WAS working, before I added a line to remove all event handlers from the server process. For some reason it just crashes at the line I just added, showing the error The "listener" argument must be of type function. Returning undefined. I don't have a clue of what to do.

Here's the parts that are relevant to my issue in the script

require("dotenv").config();                                                 // Initialize dotenv
const {Client, GatewayIntentBits, MessageType} = require("discord.js");     // Import discord.js
var spawn = require("child_process").spawn;

// Minecraft server info
mcserver = {
    dir : "", // The path to the server directory
    running : false, // Whether it's running or not
    ip : "127.0.0.1", // The server's IP address
    process : -1, // The server's spawn() process
}

// Part where the server starts
let statusBase = "Opening server...\n";
let statusMessage = await message.channel.send(statusBase + "` `"); 

mcserver.running = true;
mcserver.process = spawn("java", [
    "-Xmx1024M",
    "-Xms1024M",
    "-jar",
    "server.jar",
    /*"nogui"*/],
    {
        cwd: mcserver.dir,
    }
);

function onData (data) {
    statusMessage.edit(statusBase + "`" + data.toString() + "`");
    if (data.indexOf("Done") != -1) {
        console.log("done received");
        mcserver.process.off(); // This is the line that's throwing the error
    }
}

mcserver.process.stdout.on("data", onData);
mcserver.process.stderr.on("data", onData);

Solution

  • process is an instance of EventEmitter. EventEmitter.off (Alias to EventEmitter.removeListener) removes a listener for a specific event. You must specify the event and listener of that event that you're trying to remove. Example:

    function onData(data) {
        console.log(data.toString())
    }
    
    process.stdout.on('data', onData)
    process.stdout.off('data' onData) // Remove the onData listener from the 'data' event type
    

    You may also remove all listeners for a specific event with removeAllListeners

    process.removeAllListeners('data')
    

    To remove all listeners from an EventEmitter (for all event types), use removeAllListeners without the event type argument

    process.removeAllListeners()