Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not reference a function defined using function declaration from a debugger?

After breaking at debugger statement, trying to call foo throws ReferenceError. The function does not seem to be defined in script's context, or scope, like local x variable is.

example.js script:

/**
 * Source code example
 */

const x = 'x'
let y

function foo(param = 'foo') {
  console.log(param)
}

// const f = foo // foo throws error if commented out and referenced from debugger

debugger

Start the node process with inspector listening:

node --inspect-brk example.js

In built-in Node.js debugger:

$ node inspect 127.0.0.1:9229
Break on start in scripts/example.js:5
  3  */
  4 
> 5 const x = 'x'
  6 let y
  7 
debug> c
break in scripts/example.js:14
 12 // const f = foo // foo throws error if commented out and referenced from debugger
 13 
>14 debugger
 15 
debug> exec foo()
ReferenceError: foo is not defined
    at eval (eval at <anonymous> (/path/to/scripts/example.js:14:1), <anonymous>:1:1)
    at Object.<anonymous> (/path/to/scripts/example.js:14:1)
    at Module._compile (internal/modules/cjs/loader.js:952:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11

In VS Code's Debug Console:

foo()
ReferenceError: foo is not defined

In Chrome DevTools' Console:

foo()
VM88:1 Uncaught ReferenceError: foo is not defined
    at eval (eval at <anonymous> (/path/to/scripts/example.js:14:1), <anonymous>:1:1)
    at Object.<anonymous> (/path/to/scripts/example.js:14:1)
    at Module._compile (internal/modules/cjs/loader.js:952:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11

I find being able to test out a function with different parameters within one debugging session without restarting really useful.

like image 493
Felicio Avatar asked Jul 25 '26 22:07

Felicio


1 Answers

tldr: you need to have foo; somewhere in the same local function scope.

It seems that when you are in the debugging context, you actually do NOT have access to all the variables from the lexical scope, but rather only to those, that already appeared in this local function scope.

As Example, take this script:

const a = 'something';

(() => {
    debugger;
})()

this will produce a ReferenceError when you try to access a in the debug repl.

But if you add a; somewhere in the function scope, it's gonna work.

const a = 'something';

(() => {
    a;
    debugger;
})()

The reason why this happened to you is because function declarations are hoisted ("moved to the top of the file", but actually also outside the local function scope), whereas function expressions are not hoisted (thus already "appeared" in the function). That's why it will work when you change function foo () { to const foo = function () {.

The same thing would happen for var y; (all var variables are internally moved up - hoisted) but would work for var y = 1;, because the assign op is a kind of "appearance".

I could not find anything about this in the Reference, but from my own experience, the debugger works like this at least since node v6.

like image 137
Isalty Avatar answered Jul 27 '26 12:07

Isalty



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!