Why does VS Code break handle an exception from Reject in Promise?

Take this code, we have a promise that calls a function that will fail and it should pass the error forward to the catch method of that promise.  
It works great when ran out of the terminal. However, when running vscode, it explodes in (1).

function failingFunc() {
    let undef = undefined;
    return undef.nope();
}
let promise = new Promise((resolve, reject) => {
   resolve(failingFunc()); // (1) Explodes when run from vscode
});
promise.then(v => {}).catch((e: Error) => {
    console.log(e.message); // (2) Prints when run from the terminal
});

      

Why is this?

vscode about the page:
Version 1.14.2
Commit cb82feb
Date 2017-07-19T23: 26: 08.116Z
Shell 1.6.6
Renderer 56.0.2924.87
Node 7.4.0

+3


source to share


1 answer


Decision

As @TJCrowder pointed out in the comments:

This only happens when an exception is thrown causing a rejection before attaching a handler. For example, this would not trigger it, since when the exception converts to a rejection, there is already a rejection handler attached to it:

new Promise((resolve, reject) => setTimeout(() => { 
    try { 
        throw new Error(); 
    } catch (e) { 
        reject(e); 
    } 
}, 0)).catch(error => console.log("Error:", error));

      


It turns out to be a known "bug" when using vscode to debug Nodejs. As explained in this issue (in the vscode git repository), this happens because Nodejs dispatches a break event with an undefined

exception when it encounters a callback reject

. When the vscode debugger sees this break event, it does what it should do with unknown exceptions, it pauses execution and then throws an exception.
Further into this question (in the vscode-node-debug2 repository) @roblourens says that:

If the promise is rejected before the error handler is attached, the debugger will break even if only "thrown exceptions" are checked. If it is rejected after attaching an error handler, it works as expected. And actually the problem is how the promise doesn't know if its rejection will be processed or not.

You can still use vscode to develop Promise based systems, however you will need to disable all error handling in vscode as shown below, make sure none of the options are checked. NOTE. ... Since this is far from the optimal solution, it is likely to change and improve in the future.



(I have commented out the vscode issue and will update this post if I find out anything useful)

Edit 1:
I found another workaround is defining a keybinding in vscode to run the command workbench.action.debug.run

. This will launch the currently selected debug option without a debugger tied to it. This means that you can keep the debugger in your normal settings when running the code with a new key command when you need to deal with rejected promises.

/* keybindings.json */
[
    {
        "key": "ctrl+shift+b",
        "command": "workbench.action.debug.start"
        /* Attaches debugger */
    },
    {
        "key": "ctrl+b",
        "command": "workbench.action.debug.run"
        /* Runs without debugger */
    }
]

      

Edit2:
As @TJCrowder noted in the comments:

This only happens when an exception is thrown causing a rejection before attaching a handler. For example, this would not trigger it, since when the exception converts to a rejection, there is already a rejection handler attached to it:

new Promise((resolve, reject) => setTimeout(() => { 
    try { 
        throw new Error(); 
    } catch (e) { 
        reject(e); 
    } 
}, 0)).catch(error => console.log("Error:", error));

      

And of course he was right. The code below works in vscode with a debugger attached.

function failingFunc() {
    let undef = undefined;
    return undef.nope();
}
let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        try {
            resolve(failingFunc())
        } catch (e) {
            reject(e);
        }
    }, 0);
});
promise.then(v => {}).catch((e: Error) => {
    console.log(e.message); // Cannot read property 'nope' of undefined
});

      

+4


source







All Articles