Streams API is crashing my bot

Hey Guys,
I’m writing a Twitch chat bot in NodeJS.
It’s checking the Twitch API every 3 minutes to fetch stream stats such as FPS, delay, viewers, etc.
The problem is that occasionally the bot will completely crash, because it’s failing to fetch any information. I already have statements to ensure that it doesn’t crash because it’s null, but it still crashes occasionally. Here’s the error:

 [19:12:9]INFO: <undefined> ARENA - The current stats for user 'silver_dragon_gaming' are:
 Health: 100
 Current Health: 100
 XP: 0
 Strength: 10
 Win/Loss Ratio: 0:0

undefined:0

^
SyntaxError: Unexpected end of input
    at Object.parse (native)
    at IncomingMessage.<anonymous> (/home/mike/madgamerbot/bot.js:2398:41)
    at IncomingMessage.EventEmitter.emit (events.js:117:20)
    at _stream_readable.js:920:16
    at process._tickCallback (node.js:415:13)

The problem is at line 2398 as the error suggests. This is line 2398:

 var json = JSON.parse(body);

This is the API it’s trying to request: https://api.twitch.tv/kraken/streams/” + channel + “.json?”

Any help is greatly appreciated,

  • Mike

A friend of mine @cletusc (Creator of the Emote’s Menu) created a NodeJS package for using the Twitch API. Which also had to deal with the Twitch API not always working.
node-twitch-api

Commit to fix JSON.parse error

1 Like

It is a good idea to try catch JSON.parse though you should be checking that the request succeeded before trying to process the data, because it looks like it was trying to parse an empty string, which would suggest there was an error making the request in the first place.

Thanks for the reply. Do you have a sample of how I can check if the request succeeded? I have an if statement checking if “body == null” already, and a statement to check if json equals null or not.

Thanks, I’ll check it out!

If the page loads fine, the return will not be null.
However sometimes the API simply doesn’t return anything.

An empty string would do fine for this purpose.

However I think indeed try catching the parse is the way to go.

If you mean by checking if body is equal to null, then I’ve already tried it.

empty string. “”
just “”.

A string with nothing in it is still an object, not null.

Ahh okay, so will this fix my problem? :

    if (json.stream == "") {
        console.log("API is empty");
    }

Thanks again for the help!

You should still wrap the JSON call in a try catch.

Since null or empty is all well and good, but if you got a broken transfer (so a cut off JSON packet) or some other parse error, the try/catch works best.

That said if you get a NULL you probably got a non 200 HTTP Code.

So, make the HTTP request.
Then check the HTTP Code for a 200
Ignore/error out/stop any non 200’s as thats a server side error
Then if you do get a 200 OK, then continue to the JSON parsing.
But still wrap that in a try/catch.

Basically, check the HTTP Error Code for a 200 (OK)

The need of try/catch in a live script such as yours cannot be avoided. This is a great scenario for what it was made to do. There’s no need to shift to another library if you’ve already got the code written how you like

try {

   // try to get or post to the api here
   // as long as twitch returns a response, null or otherwise
   // then the attempt was successful and code continues executing
   // note: it skips the error block of code

} catch(error) {

   // if the get or post failed due to connection errror, timeout, etc ..
   // this area of code will fire
   // the variable `error` will contain any useable data about the error
   // also, despite the error, the script will continue executing further

}
1 Like

Thanks for the reply Barry.
Do you have a sample of how I can get the returned code? I’m fairly new to the HTTP(S) module, so I’m not sure how I get the error code. :stuck_out_tongue:

I’ll give this a try, thanks!

I’ve taken a look at my function that handles all of this, and one thing I noticed is that it’s checking the chatters API inside of this other API function check… The problem I noticed is that I copied and pasted that API function from a separate function (to merge them both together), and forgot to put it inside the if statements that make sure it’s not null… This could possibly be why, we’ll soon find out. I’ve also implemented a try statement as suggested by QwisoDev !

Thanks for the replies guys, I’ll keep you updated as to how this goes.

Instead of using what you are using try the request module instead

Heres a sample use. (It’s for converting a twitch name to it’s cased user set version)

request('https://api.twitch.tv/kraken/users/' + who.toLowerCase(), function (error, response, body) {
    if (error) {
        console.log(error);
    } else if (response.statusCode != 200) {
       console.log('HTTP: ' + response.statusCode);
    } else {
        try {
            body = JSON.parse(body);
            who = body.display_name;
        } catch (Err) {   
           console.log('JSON Parse Error: ' + err);
        }
    }
    // do something with who
});

Ohhh thanks for that, I’ll give this a try, it looks much more effective for debugging.

I appreciate the help!

I gave this a try and put my entire API check inside the try statement, but it doesn’t appear to work… Now all I’m getting is this error:

    events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: getaddrinfo ENOTFOUND. Hostname: https://tmi.twitch.tv
    at errnoException (dns.js:37:11)
    at Object.onanswer [as oncomplete] (dns.js:124:16)

I figured out which API was giving the problem, which is the chatter’s list. I’ve disabled it for now because it’s on Twitch’s end, but I’m still confused as to why the try/catch didn’t catch the error and prevent the crashes

Use request for that too.

But that error should be catchable with a .on('error', function(err) call somewhere…

I find that the chatters list is very 50x error codey recently.

Yeah I’ve just completely given up on the chatters list until it’s resolved.

The try catch statement is now gathering a lot of errors which I’m actually glad about, now I don’t have to worry about checking the server every 30 minutes no matter where I am to make sure the bot is still alive haha.

I expect the AWS migration would break a lot so I’m just going to wait for things to calm down a bit.
One thing I’ve noticed a lot too is the chat servers kicking bots off, which again I assume is the migration.

Sorry for the late reply also, honestly not sure why it took so long!

After letting the bot run for a few weeks, it has now stopped crashing. The error that I mentioned in the original post is still occurring, but it’s now logging it rather than crashing. I’ll mark this as the nearest solution!