microsoft/vscode-chrome-debug-core

Debugger crashes with TypeError: Cannot read property 'url' of undefined

jhnns opened this issue · 1 comments

jhnns commented

When I'm trying to debug my code with VS Code, the debugger fails and logs the following stack trace to the debug console:

******** Unhandled error in debug adapter: TypeError: Cannot read property 'url' of undefined
    at isLogpointMessage (/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/ms-vscode.node-debug2/node_modules/vscode-chrome-debug-core/out/src/chrome/internalSourceBreakpoint.js:28:54)
    at Object.stackTraceWithoutLogpointFrame (/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/ms-vscode.node-debug2/node_modules/vscode-chrome-debug-core/out/src/chrome/internalSourceBreakpoint.js:31:9)
    at NodeDebugAdapter.onConsoleAPICalled (/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/ms-vscode.node-debug2/node_modules/vscode-chrome-debug-core/out/src/chrome/chromeDebugAdapter.js:955:50)
    at NodeDebugAdapter.onConsoleAPICalled (/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/ms-vscode.node-debug2/out/src/nodeDebugAdapter.js:382:19)
    ...

The problem comes from this line where callFrames is expected to be an array with at least one item:

function isLogpointMessage(m: Crdp.Runtime.ConsoleAPICalledEvent): boolean {
    return m.stackTrace && m.stackTrace.callFrames[0].url === InternalSourceBreakpoint.LOGPOINT_URL;
}

At the time when the error happens, m looks like:

{
    "type": "error",
    "args": [
        {
            "type": "object",
            "subtype": "error",
            "className": "NodeError",
            "description":
                "NodeError: The \"path\" argument must be one of type string, Buffer, or URL. Received type object\n    at readdir (internal/fs/promises.js:298:3)\n    at CallEffect.exec (/Users/jhnns/dev/peerigon/2fp/effect/call.js:16:22)\n    at MultiTickContinuation.[tick] (/Users/jhnns/dev/peerigon/2fp/lib/run.js:130:24)\n    at new MultiTickContinuation (/Users/jhnns/dev/peerigon/2fp/lib/run.js:67:9)\n    at fork (/Users/jhnns/dev/peerigon/2fp/lib/run.js:153:26)\n    at MultiTickContinuation.fork (/Users/jhnns/dev/peerigon/2fp/lib/run.js:82:16)\n    at ForkEffect.exec (/Users/jhnns/dev/peerigon/2fp/effect/fork.js:17:35)\n    at MultiTickContinuation.[tick] (/Users/jhnns/dev/peerigon/2fp/lib/run.js:130:24)\n    at new MultiTickContinuation (/Users/jhnns/dev/peerigon/2fp/lib/run.js:67:9)\n    at fork (/Users/jhnns/dev/peerigon/2fp/lib/run.js:153:26)",
            "objectId": "{\"injectedScriptId\":1,\"id\":37}",
            "preview": {
                "type": "object",
                "subtype": "error",
                "description":
                    "NodeError: The \"path\" argument must be one of type string, Buffer, or URL. Received type object\n    at readdir (internal/fs/promises.js:298:3)\n    at CallEffect.exec (/Users/jhnns/dev/peerigon/2fp/effect/call.js:16:22)\n    at MultiTickContinuation.[tick] (/Users/jhnns/dev/peerigon/2fp/lib/run.js:130:24)\n    at new MultiTickContinuation (/Users/jhnns/dev/peerigon/2fp/lib/run.js:67:9)\n    at fork (/Users/jhnns/dev/peerigon/2fp/lib/run.js:153:26)\n    at MultiTickContinuation.fork (/Users/jhnns/dev/peerigon/2fp/lib/run.js:82:16)\n    at ForkEffect.exec (/Users/jhnns/dev/peerigon/2fp/effect/fork.js:17:35)\n    at MultiTickContinuation.[tick] (/Users/jhnns/dev/peerigon/2fp/lib/run.js:130:24)\n    at new MultiTickContinuation (/Users/jhnns/dev/peerigon/2fp/lib/run.js:67:9)\n    at fork (/Users/jhnns/dev/peerigon/2fp/lib/run.js:153:26)",
                "overflow": false,
                "properties": [
                    {
                        "name": "stack",
                        "type": "string",
                        "value":
                            "TypeError [ERR_INVALID_ARG_TYPE]: The \"path\" argum…(/Users/jhnns/dev/peerigon/2fp/lib/run.js:153:26)"
                    },
                    {
                        "name": "message",
                        "type": "string",
                        "value":
                            "The \"path\" argument must be one of type string, Buffer, or URL. Received type object"
                    }
                ]
            }
        }
    ],
    "executionContextId": 1,
    "timestamp": 16183802.376826,
    "stackTrace": {
        "callFrames": [], // <----- empty array
        "parent": {
            "description": "Promise.then",
            "callFrames": [
                {
                    "functionName": "",
                    "scriptId": "925",
                    "url": "/Users/jhnns/dev/peerigon/2fp/example/rstat/index.js",
                    "lineNumber": 6,
                    "columnNumber": 0
                },
                {
                    "functionName": "Module._compile",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 701,
                    "columnNumber": 29
                },
                {
                    "functionName": "loader",
                    "scriptId": "891",
                    "url": "/Users/jhnns/dev/peerigon/2fp/node_modules/babel-register/lib/node.js",
                    "lineNumber": 143,
                    "columnNumber": 4
                },
                {
                    "functionName": "require.extensions.(anonymous function)",
                    "scriptId": "891",
                    "url": "/Users/jhnns/dev/peerigon/2fp/node_modules/babel-register/lib/node.js",
                    "lineNumber": 153,
                    "columnNumber": 6
                },
                {
                    "functionName": "Module.load",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 611,
                    "columnNumber": 31
                },
                {
                    "functionName": "tryModuleLoad",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 550,
                    "columnNumber": 11
                },
                {
                    "functionName": "Module._load",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 542,
                    "columnNumber": 2
                },
                {
                    "functionName": "Module.runMain",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 743,
                    "columnNumber": 9
                },
                {
                    "functionName": "",
                    "scriptId": "64",
                    "url": "/Users/jhnns/dev/peerigon/2fp/node_modules/babel-cli/lib/_babel-node.js",
                    "lineNumber": 153,
                    "columnNumber": 21
                },
                {
                    "functionName": "Module._compile",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 698,
                    "columnNumber": 13
                },
                {
                    "functionName": "Module._extensions..js",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 712,
                    "columnNumber": 9
                },
                {
                    "functionName": "Module.load",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 611,
                    "columnNumber": 31
                },
                {
                    "functionName": "tryModuleLoad",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 550,
                    "columnNumber": 11
                },
                {
                    "functionName": "Module._load",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 542,
                    "columnNumber": 2
                },
                {
                    "functionName": "Module.runMain",
                    "scriptId": "57",
                    "url": "internal/modules/cjs/loader.js",
                    "lineNumber": 743,
                    "columnNumber": 9
                },
                {
                    "functionName": "startup",
                    "scriptId": "14",
                    "url": "internal/bootstrap/node.js",
                    "lineNumber": 237,
                    "columnNumber": 18
                },
                {
                    "functionName": "bootstrapNodeJSCore",
                    "scriptId": "14",
                    "url": "internal/bootstrap/node.js",
                    "lineNumber": 571,
                    "columnNumber": 2
                }
            ]
        }
    }
}

You can clearly see that stackTrace.callFrames is an empty array in my case.

I'm running the debugger task with node v10.3.0 using the babel-node executable. babel-cli (where the babel-node executable is coming from) is at v6.26.0.

In my example code, I'm calling fs.readdir with something different than a string which caused the original error. I'm using node's fs promise API which might be the cause for the empty callFrames: Maybe node is calling the code from native code?

A simple fix for that error would be to add a guard to the array access to make sure that callFrames is an array with at least one element.

If you want to investigate the error, I can setup a minimal reproducible test repo.

Yeah I think you're right that it's thrown from native code with no user-code frames. Thanks for the PR!