pg-pool swallows errors #24
Comments
Is this project still maintained? |
Yes. On Wednesday, August 24, 2016, Stephen Cresswell notifications@github.com
|
@cressie176 This caused by promise's default behavior.(Promise will do no thing, when you did not catch a reject).
|
Hi @iamchenxin. Thanks for the response. I'm using the callback API so not able to catch a reject. Also listening process.on('unhandledRejection') isn't going to help much since that could be caused by any unhandled rejection, not specifically one raised by the pg internals. I'd definitely argue that this is a bug with pg (or one of its libs) since users of the callback API shouldn't need to understand the libraries internals. By convention any errors should be passed the callback via the err argument. |
@cressie176 look it again, seems this is not only belong to Or You could temporaryily chain a catch below your original function.
I agree with you, and also think may be the callback's behavior should be separated from promise in source code. |
Thanks again @iamchenxin. Both those options (bluebird and catch) work with my simplified example, but unfortunately aren't viable options with the real code. The problem is that the Bluebird intercepts unhandled rejection and logs it, but there's still no way (I've been able to find) to do anything intelligent with the error. catching the error after each call does appear to work, but doing that renders the callback API worse than pointless for two reasons
|
@cressie176
|
Thanks for your time and explanation @iamchenxin . Unless @brianc has any good suggestions I don't think I'll just have to live with the unhandledRejection approach. |
@cressie176 sorry I've been a bit AWOL - I get busy & things fall by the wayside. I definitely want to fix this - having errors disappear without warning is a pretty big problem. I'll move it to the top of my queue and get to it soon. I really appreciate the example you submitted as a clear case for how to reproduce the issue. I'll ping you when I put the pull request. @iamchenxin thanks for the investigation you did! It may indeed require a bit of rewriting - I'd like to end up at a place where the functionality can be maintained. If there is no way to do it in a backwards compatible way it may take a bit longer. In the next major version of pg we want to ship node-postgres core without promises, pg-pool without promises, and ship |
Thanks @brianc, that's perfect. I like the idea of shipping a promise free postgres-core, with an optional as promised wrapper. No need to apologise for being AWOL, I really appreciate the effort you and the other contributors have put in node-postgres. |
+1 here's my situation |
It’s incorrect to do so. One consequence is that a rejected promise will be unhandled, which is currently annoying, but also dangerous in the future: > DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. The way callbacks are used currently also causes brianc#24 (hiding of errors thrown synchronously from the callback). One fix for that would be to call them asynchronously from inside the `new Promise()` executor: process.nextTick(cb, error); I don’t think it’s worth implementing, though, since it would still be backwards-incompatible – just less obvious about it.
It’s incorrect to do so. One consequence is that a rejected promise will be unhandled, which is currently annoying, but also dangerous in the future: > DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. The way callbacks are used currently also causes brianc#24 (hiding of errors thrown synchronously from the callback). One fix for that would be to call them asynchronously from inside the `new Promise()` executor: process.nextTick(cb, error); I don’t think it’s worth implementing, though, since it would still be backwards-incompatible – just less obvious about it.
It’s incorrect to do so. One consequence is that a rejected promise will be unhandled, which is currently annoying, but also dangerous in the future: > DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. The way callbacks are used currently also causes brianc#24 (hiding of errors thrown synchronously from the callback). One fix for that would be to call them asynchronously from inside the `new Promise()` executor: process.nextTick(cb, error); I don’t think it’s worth implementing, though, since it would still be backwards-incompatible – just less obvious about it. Also fixes a bug where the `Pool.prototype.connect` callback would be called twice if there was an error.
* Revert "When connection fail, emit the error. (#28)" This reverts commit 6a7edab. The callback passed to `Pool.prototype.connect` should be responsible for handling connection errors. The `error` event is documented to be: > Emitted whenever an idle client in the pool encounters an error. This isn’t the case of an idle client in the pool; it never makes it into the pool. It also breaks tests on pg’s master because of nonspecific dependencies. * Don’t create promises when callbacks are provided It’s incorrect to do so. One consequence is that a rejected promise will be unhandled, which is currently annoying, but also dangerous in the future: > DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. The way callbacks are used currently also causes #24 (hiding of errors thrown synchronously from the callback). One fix for that would be to call them asynchronously from inside the `new Promise()` executor: process.nextTick(cb, error); I don’t think it’s worth implementing, though, since it would still be backwards-incompatible – just less obvious about it. Also fixes a bug where the `Pool.prototype.connect` callback would be called twice if there was an error. * Use Node-0.10-compatible `process.nextTick`
UPDATE: return await this.select(data).rows Trying to access a property/method of the return object of an async/await execution, seems to silently break the await and it is automatically converted to a normal async call. I have also a very very weird behavior... never had this before. Sounds slightly like this issue: I can use the pool.connect() a few times... but suddenly when creating a client it just exits the function while debugging... I tried to get any error but it seems to be impossible to get any information: if(debug===true) {
this._pool.connect().then(client=> { // is not exiting the further interpreter flow
console.log('whoot?') // never shown or breakpoint hit
}).catch(ex=> {
console.log(ex.message) // never shown or breakpoint hit
})
} else {
try {
client = await this._pool.connect() // immediately exits the current interpreter flow and method hard
} catch(ex) {
console.log(ex.message) // never shown or breakpoint hit
} finally {
console.log('WHY?') // never shown or breakpoint hit
}
} catch/finally does never execute... and there is no message on the console, breakpoints doesnt work either. I also activated process.on('unhandledRejection', (err) => {
console.error(err)
process.exit(1)
}) Also this is useless for this issue: this._pool.on('error', (err, client) => {
let { logger } = self.loadModules()
logger.logCritical(err.message, 'Database error', err)
}) But it doesnt help. As soon as the interpreter (via debugging) hits the connect(), the surrounding method returns undefined regardless of any try/catch/finally around, or callback used to get some information. Has anyone a suggestion? |
I'm seeing strange behaviour when using pg-pool. The following script demonstrates the problem
Instead of crashing, the error is swallowed. I noticed this because my code was programatically building a query, and thew an error because of an undefined variable. e.g.
The text was updated successfully, but these errors were encountered: