martynsmith / node-irc

NodeJS IRC client library
GNU General Public License v3.0
1.32k stars 425 forks source link

The framework constantly crashes - "Cannot call method 'replace' of undefined" #364

Closed Zamiell closed 9 years ago

Zamiell commented 9 years ago

I'm not sure what exactly causes this, but my IRC bot routinely crashes over the course of normal operation. The error message is always the same:

TypeError: Cannot call method 'replace' of undefined
    at /opt/ZamielBot/node_modules/irc/lib/irc.js:278:71
    at Array.forEach (native)
    at Client.<anonymous> (/opt/ZamielBot/node_modules/irc/lib/irc.js:259:26)
    at Client.emit (events.js:95:17)
    at iterator (/opt/ZamielBot/node_modules/irc/lib/irc.js:756:26)
    at Array.forEach (native)
    at Socket.<anonymous> (/opt/ZamielBot/node_modules/irc/lib/irc.js:751:15)
    at Socket.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:765:14)
    at Socket.emit (events.js:92:17)

My bot will just echo traffic from one IRC server to another. Here is the source code:

#! /usr/bin/env node

/* Variables */
var irc = require('irc');
var SRLBot = new irc.Client('irc.speedrunslive.com', 'ZamielBot', {
    debug: true,
    channels: ['#speedrunslive']
});
var TwitchBot = new irc.Client('irc.twitch.tv', 'ZamielBot', {
    debug: true,
    channels: ['#zamiell'],
    password: 'asdf'
});

/* Catch errors */
SRLBot.addListener('error', function(message) {
    console.error('SRL ERROR: %s: %s', message.command, message.args.join(' '));
});
TwitchBot.addListener('error', function(message) {
    console.error('TWITCH ERROR: %s: %s', message.command, message.args.join(' '));
});

/* Catch messages */
SRLBot.addListener('message', function(user, channel, message) {
    console.log('SRL [%s] <%s> %s', channel, user, message);
    TwitchBot.say('#zamiell', '<' + user + '> ' + message);
});
TwitchBot.addListener('message', function(user, channel, message) {
    console.log('Twitch [%s] <%s> %s', channel, user, message);
});

I'm assuming that the error lies in the framework, as the bot code is relatively simple. Can anyone shed some insight?

sim642 commented 9 years ago

The line on which the error happens seems to be regarding user modes in channel which have been known to be an issue with twitch IRC (#340). Although I don't think it should still be crashing maybe you could try using another network to test if it still happens.

Zamiell commented 9 years ago

So perhaps when a moderator enters my Twitch chat, the bot will crash? I will test this.

Zamiell commented 9 years ago

Having a moderator enter the channel does not cause the crash. It must be something else. Output from the script:

14 May 11:26:32 - MODE: #zamiell sets mode: +o
sim642 commented 9 years ago

The erroring line has to do with mode removal. Maybe Twitch does something weird when moderators leave?

Zamiell commented 9 years ago

That was it! That causes the crash. Is there a way to turn on a deep debugging mode or something so that I can see the raw IRC message that is being sent to the framework? If not, let me know what else you need me to do. =)

sim642 commented 9 years ago

I'm guessing right now that Twitch's IRC implementation sends MODE when a moderator leaves but in actual IRC protocol that is not necessary. There is an debug: true option you can set for a Client but I'm not sure if that reveals anything more.

Also, I don't actually develop or maintain node-irc so I don't really "need" anything.

Zamiell commented 9 years ago

Yeah, I already have debug: true set, but it doesn't give me that kind of granularity. While I wait for an official maintainer to respond, are you familiar enough with the code to suggest a patch to stop this particular crashing? (As it would be nice to have an interim fix for the issue before the official repo is patched.)

sim642 commented 9 years ago

This is completely untested but adding an extra check should avoid it from trying to manipulate the impossible:

--- /home/simmo/Desktop/irc.js
+++ /home/simmo/Desktop/irc2.js
@@ -268,15 +268,17 @@
                     if (mode in self.prefixForMode) {
                         // channel user modes
                         var user = modeArgs.shift();
-                        if (adding) {
-                            if (channel.users[user] && channel.users[user].indexOf(self.prefixForMode[mode]) === -1)
-                                channel.users[user] += self.prefixForMode[mode];
-
-                            self.emit('+mode', message.args[0], message.nick, mode, user, message);
-                        }
-                        else {
-                            channel.users[user] = channel.users[user].replace(self.prefixForMode[mode], '');
-                            self.emit('-mode', message.args[0], message.nick, mode, user, message);
+                        if (user in channel.users) {
+                            if (adding) {
+                                if (channel.users[user] && channel.users[user].indexOf(self.prefixForMode[mode]) === -1)
+                                    channel.users[user] += self.prefixForMode[mode];
+
+                                self.emit('+mode', message.args[0], message.nick, mode, user, message);
+                            }
+                            else {
+                                channel.users[user] = channel.users[user].replace(self.prefixForMode[mode], '');
+                                self.emit('-mode', message.args[0], message.nick, mode, user, message);
+                            }
                         }
                     }
                     else {
Zamiell commented 9 years ago

Thank you so much! I'll give it a whirl later on tonight when I get home from work. =D

Zamiell commented 9 years ago

Looks like this fix works! Thanks again sim642.

ghost commented 9 years ago

This should be merged into master. I'm getting crashes on Freenode too:

/home/lorenzo/bot/node_modules/irc/lib/irc.js:748
                        throw err;
                              ^
TypeError: Cannot call method 'replace' of undefined
    at /home/lorenzo/bot/node_modules/irc/lib/irc.js:278:71
    at Array.forEach (native)
    at Client.<anonymous> (/home/lorenzo/bot/node_modules/irc/lib/irc.js:259:26)
    at Client.emit (events.js:95:17)
    at iterator (/home/lorenzo/bot/node_modules/irc/lib/irc.js:745:26)
    at Array.forEach (native)
    at Socket.<anonymous> (/home/lorenzo/bot/node_modules/irc/lib/irc.js:740:15)
    at Socket.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:765:14)
    at Socket.emit (events.js:92:17)
error: Forever detected script exited with code: 8
error: Script restart attempt #66