When I create a Promise.all()
call with a promise that never resolves, instead of throwing an error, it just silently kills the program, even if other things are going on (e.g. running a server).
Here's minimal code:
[expected: "done!" or an error or something, please]
async function a(){
await Promise.all([new Promise((resolve)=>{
})]);
console.log("done!");
}
a();
Unresolved promises do not keep a process alive. And I can't reproduce that the process exits "even if other things are going on (e.g. running a server)"
Promise died from pending state
:)
Alright, fair call - but can I ask: how am I meant to debug this behaviour? And are there cases where this behaviour could ever be useful?
Knowing whether a promise will be resolved or not is better generalized as something called the halting problem. It isn't possible to know whether or not code will run that will resolve a promise. In addition to this, unresolved promises don't keep the application alive, because they don't do anything, they're just a fancy way to call a callback.
I know that people have looked into finding ways to list unresolved Promises at process exit – and I think that would be the right debugging tool here – but that requires support from upstream V8 that we don’t have so far (or some userland module using async_hooks, I think).
You can do that with async_hooks now, register promises when they're created and remove them from the list when they're resolved.
You can also do it through the inspector API, with Runtime.awaitPromise
. I have some working code from a larger project that I'll try to break out and publish as a separate module. Here is a gist that shows the basic concept:
https://gist.github.com/bnoordhuis/e4f935a0c81c477533c9bdc54b22e837
I think this is not a problem. Because the promise will not change the activeRequests
or activeHandles
. The event-loop
will be exited if the activeRequests
equals to 0 or activeHandles
equals to 0.
It decides by libuv
I think this should be closed. The promise that never resolves can't possible affect the program. If node exits, that means that all pending promises could never be resolved, because there is noting going on with the event loop. In fact, such promises might be even garbage collected at this point. Indeed, promises just represent callbacks, not some pending processes that should keep node process alive.
Just got into this issue. It is frustrated to debug without an message printed to console, telling the programmer that the progress is exited without an ever-pending Promise being resolved.
A warning message printed to the console would have saved my day.
Most helpful comment
Knowing whether a promise will be resolved or not is better generalized as something called the halting problem. It isn't possible to know whether or not code will run that will resolve a promise. In addition to this, unresolved promises don't keep the application alive, because they don't do anything, they're just a fancy way to call a callback.