javascriptnode.jstypescriptnpm

Is it possible to log the stack trace where a variable changes?


I want to change a certain variable every second. But the same variable is changing on multiple places of them, and one of them is resulting in NaN. I can't seem to find out what exactly is causing that. Is there a way to log the stack trace where it changes? Take for example this code:

let foo = 0;

for (foo = 0; foo < 5; foo++) {
  // Do something
}

if (isNaN(foo)) {
  // Console.log the stack trace where the variable changes into NaN
}

Is it possible to do this in one, two or three lines without having to change too much logic or adding too much things in order for it to work? It is node.js-compatible, so it can be a NPM package if that's easier.


Solution

  • If foo is in an object, you could wrap that object in a proxy that will report when certain properties change. The proxy object below will call console.trace when a property is set with a key that was passed as part of the propsToWatch array.

    function propertyWatcher<T extends object>(
      target: T,
      ...propsToWatch: (keyof T)[]
    ) {
      return new Proxy(target, {
        set: (tgt, key, value) => {
          if (propsToWatch.includes(key as keyof T)) {
            console.trace(`changing "%s" from %o to %o in %o`, key, (tgt as any)[key], value, tgt);
          }
          (tgt as any)[key] = value;
          return true;
        },
      });
    }
    

    Usage

    const fooHost = { foo: 1 };
    
    const fooHostProxy = propertyWatcher(fooHost, 'foo');
    
    function setFooAndBar() {
      fooHostProxy.foo = 2;
    }
    
    setFooAndBar();
    

    Output

    changing "foo" from 1 to 2 in {foo: 1, bar: 1} 
    set          @ main.ts:10
    setFooAndBar @ main.ts:24