ddsol / speedtest.net

node.js SpeedTest.net client module
MIT License
611 stars 124 forks source link

Cannot read property 'servers' of undefined #25

Closed irvingswiftj closed 8 years ago

irvingswiftj commented 8 years ago

Since this morning, my application gets the following error when performing a speediest:

TypeError: Cannot read property 'servers' of undefined
    at gotServers (/myproject/node_modules/speedtest-net/index.js:522:29)
    at /myproject/node_modules/speedtest-net/index.js:48:16
    at /myproject/node_modules/speedtest-net/index.js:238:7
    at Parser.<anonymous> (/myproject/node_modules/speedtest-net/node_modules/xml2js/lib/xml2js.js:489:18)
    at emitOne (events.js:77:13)
    at Parser.emit (events.js:169:7)
    at Object.onclosetag (/myproject/node_modules/speedtest-net/node_modules/xml2js/lib/xml2js.js:447:26)
    at emit (/myproject/node_modules/speedtest-net/node_modules/xml2js/node_modules/sax/lib/sax.js:640:35)
    at emitNode (/myproject/node_modules/speedtest-net/node_modules/xml2js/node_modules/sax/lib/sax.js:645:5)
    at closeTag (/myproject/node_modules/speedtest-net/node_modules/xml2js/node_modules/sax/lib/sax.js:905:7)
    at Object.write (/myproject/node_modules/speedtest-net/node_modules/xml2js/node_modules/sax/lib/sax.js:1449:13)
    at Parser.exports.Parser.Parser.parseString (/myproject/node_modules/speedtest-net/node_modules/xml2js/lib/xml2js.js:508:31)
    at Parser.parseString (/myproject/node_modules/speedtest-net/node_modules/xml2js/lib/xml2js.js:7:59)
    at exports.parseString (/myproject/node_modules/speedtest-net/node_modules/xml2js/lib/xml2js.js:540:19)
    at /myproject/node_modules/speedtest-net/index.js:236:5
    at /myproject/node_modules/speedtest-net/index.js:48:16
    at IncomingMessage.<anonymous> (/myproject/node_modules/speedtest-net/index.js:110:7)
    at emitNone (events.js:72:20)
    at IncomingMessage.emit (events.js:166:7)
    at endReadableNT (_stream_readable.js:905:12)
    at doNTCallback2 (node.js:441:9)
    at process._tickDomainCallback (node.js:396:17)
[root@foobar myproject]# vim /myproject/libs/Main.js
ddsol commented 8 years ago

I changed the user agent and it works well for me. See if the new version works for you as well.

c0bra commented 8 years ago

@ddsol It's still failing with the same error for me as of 1.2.6

events.js:160
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property 'settings' of null
    at gotServers (path\to\my\project\node_modules\speedtest-net\index.js:522:20)
c0bra commented 8 years ago

Problem is that servers is null here:

 function gotServers(err, servers) {
    if (err) return self.emit('error', err);
    var s = servers.settings.servers[0].server;
   ...
ddsol commented 8 years ago

So, it loads http://www.speedtest.net/speedtest-servers.php from the interwebs and then it pushes the result through some kind of XML detangler which I found on npm. It seems in your case it presents with null. In my case it does, however, not. When I visit the link above I get some XML about what servers are where, for instance from. I can't know why you're not getting any servers, but I am suspicious that maybe you're calling it quite a bit and Ookla has taken your IP and kind of blocked it. You can visit that link in your browser and see what you get. If you get issues in your browser, then it's probably your IP that is being rejected.

To be clear, this module doesn't provide all those servers. That is being done by Ookla. And I don't know how Ookla feels about this module. It may attempt to block it. If it's successful, then it should stop working. One entity's success may be another's demise.

My advice is to not use it too often. Unless your connection speed varies wildly, or you swap providers like you swap socks, there should be no need to check it too often. Ookla would likely not notice you if you're a gentle user.

Maybe it's something else, which I can't know because as I stated above, it works just wonderfully for me. You could console.log the data available on line 235/236. That ought to be valid XML and if and when this is not the case, you may be lucky to get a detailed error, like "Too many requests" or "Please use the official Speedtest.net client". If you're not lucky you just get nothing. If you do get valid XML then something else is the matter and I might just be prodded into looking at it some more.

In the meantime, though I am willing, I am not able to help any further.

christoph-neumann commented 8 years ago

It looks like http://www.speedtest.net/speedtest-servers.php is returning a 302 redirect now. Does getHttp follow that redirect?

$ curl -v http://www.speedtest.net/speedtest-servers.php
*   Trying 72.21.92.82...
* Connected to www.speedtest.net (72.21.92.82) port 80 (#0)
> GET /speedtest-servers.php HTTP/1.1
> Host: www.speedtest.net
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< Content-Type: text/html
< Date: Thu, 14 Jul 2016 23:42:54 GMT
< Location: http://c.speedtest.net/speedtest-servers-static.php?load=1
< Server: ECD (rhv/8107)
< Content-Length: 0

If I do a curl with the provided URL, it works: curl -v http://c.speedtest.net/speedtest-servers-static.php?load=1

ddsol commented 8 years ago

Yeah, so it does follow the redirect, I think, probably: it works fine for me. I don't know what result is gotten by this module here by those who it does not work for, and me checking this doesn't help because it works just fine for me so I won't get any anomalies.

I suggest attempting to set { headers: { "user-agent" : "my own special user agent; feel free to be creative here; version v3.4.5.beta.carotene webkit blink bing bling bey marquee google firefox windows osx linux unix apple commodore msx pear mozilla 4/12 php visual basic.web" } }, because maybe this will prompt speedtest.net to return some servers considering the server doesn't recognise the UA as anything special (even though it's actually inredibly special, go figure).

Again, if someone were to be so kind as to do a simple console.log(data) here then that might be tremendously helpful and useful. Also, if someone that experiences the issue tries a manual UA setting, it would be great if they can report their results.

In the meantime I don't have any means of finding out what the problem is because I do not experience it.

christoph-neumann commented 8 years ago

I added a console.log(data) and data is an empty string. I added some logging in getHttp:

console.log(res.statusCode)
console.log(res.headers)

And this is what I got:

302
{ 'content-type': 'text/html',
  date: 'Fri, 15 Jul 2016 00:07:56 GMT',
  location: 'http://c.speedtest.net/speedtest-servers-static.php?load=1',
  server: 'ECD (rhv/8107)',
  'content-length': '0',
  connection: 'close' }

So, it's definitely not following the 302 redirect.

christoph-neumann commented 8 years ago

The node http library doesn't follow redirects. It looks like request is the most popular library that follows redirects by default.

https://github.com/request/request

ddsol commented 8 years ago

Well, that is awesome news. Strange that it still works for me, because it does redirect in my browser. In any case, it should be a quick fix with this knowledge. If I don't find a PR soon then I will just go ahead and make the change myself. When I have a few minutes...

jssuttles commented 8 years ago

I still get this error.

jssuttles commented 8 years ago

Here's load=0.

screen shot 2016-09-25 at 3 37 43 pm

Here's load=1.

screen shot 2016-09-25 at 3 37 35 pm

Anybody have any ideas why load=1, which is what it redirects to by default, is blank?