Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting when any variable in a large JS program is set to NaN

I have a large, messy JS codebase. Sometimes, when the app is being used, a variable is set to NaN. Because x = 2 + NaN results in x being set to NaN, the NaN it spreads virally. At some point, after it has spread pretty far, the user notices that there are NaNs all over the place and shit generally doesn't work anymore. From this state, it is very difficult for me to backtrack and identify the source of the NaN (and there could very well be multiple sources).

The NaN bug is also not easily reproducible. Despite hundreds of people observing it and reporting it to me, nobody can tell me a set of steps that lead to the appearance of NaNs. Maybe it is a rare race condition or something. But it's definitely rare and of uncertain origins.

How can I fix this bug? Any ideas?

Two stupid ideas I've thought of, which may not be feasible:

  1. Write some kind of pre-processor that inserts isNaN checks before every time any variable is used and logs the first occurrence of NaN. I don't think this has been done before and I don't know how hard it would be. Any advice would be appreciated.

  2. Run my code in a JS engine that has the ability to set a breakpoint any time any variable is set to NaN. I don't think anything does this out of the box, but how hard would it be to add it to Firefox or Chrome?

I feel like I must not be the first person to have this type of problem, but I can't find anyone else talking about it.

like image 637
dumbmatter Avatar asked Oct 25 '14 14:10

dumbmatter


1 Answers

There is probably no solution for your problem aka: break, whenever any variable is set to NaN. Instead, you could try to observe your variables like this:

  • It was earlier stated, that the Chrome debugger offers conditional breakpoints. But, it also supports to watch expressions. In the Watch-Expressions menu you can set a condition to break, whenever the variable is set to a specific value.

  • Object.observe is a method that observes changes on a object. You are able to listen to all changes on the object, and call debug when any variable is set to NaN. For example, you could observe all change on the window object. Whenever any variable on the window object is set to NaN, you call debug. Please note, that Object.observe is quite cutting edge and not supported by all browsers (check out the polyfill in this case).

  • Take this opportunity to write a test case for every function in your code. Perform random testing and find the line of code that can create NaN values.

Another problem of yours is probably how to reproduce this error. Reloading your webpage over and over doesn't make too much sense. You could check out a so called headless browser: It starts an instance of a browser without displaying it. It can be leveraged to perform automatic tests on the website, click some buttons, do some stuff. Maybe you can script it in such a way that it finally reproduces your error. This has the advantage that you don't have to reload your webpage hundreds of times. There are several implementations for headless browsers. PhantomJS is really nice, in my opinion. You can also start a Chrome Debug Console with it (you need some plugin: remote debugger).

Furthermore, please notice that NaN is never equal to NaN. It would be a pity if you finally are able to reproduce the error, but your breakpoints don't work.

like image 150
dmonad Avatar answered Sep 19 '22 02:09

dmonad