-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Implement a PoolError
with dedicated codes
#2498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Previously the Pool was throwing built-in JS `Error`. It's therefore difficult to identify each kind of error. This patch allow the developer to identify each type of error raised by the Pool with a `PoolError`. Each `PoolError` has its own code and a message (original message for backward compatibility). Codes and errors are documented in README file.
@@ -331,6 +331,20 @@ var bluebirdPool = new Pool({ | |||
|
|||
__please note:__ in node `<=0.12.x` the pool will throw if you do not provide a promise constructor in one of the two ways mentioned above. In node `>=4.0.0` the pool will use the native promise implementation by default; however, the two methods above still allow you to "bring your own." | |||
|
|||
## error management | |||
|
|||
Errors throwed by the pool are instances of `PoolError`. Each `PoolError` has a message (short description of the exception) and a structured code composed of 5 characters string starting with letter `Z`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- How about meaningful text like the error codes in the Node standard library?
- I’m not sure if most of these deserve their own code. Nobody should be handling library misuse like multiple release, multiple end, use after end, or type errors programmatically. “Timeout exceeded when trying to connect” makes sense, though.
- throwed → thrown
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about meaningful text like the error codes in the Node standard library?
Current implementation mimic the NoticeOrError
interface from pg-protocol
, cf this message
Nobody should be handling library misuse like multiple release, multiple end, use after end, or type errors programmatically.
That's why it raises exceptions errors.
“Timeout exceeded when trying to connect” makes sense, though.
That's actually the only one I want to catch for now. For instance in a HTTP API, my goal is to return (a more) meaningful message to the client (in this case a 503
which means that the service is unavailable for now).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think mimicking the format of PostgreSQL error codes (with values that don’t come from PostgreSQL) is useful. https://nodejs.org/api/errors.html#nodejs-error-codes
module.exports.Pool = Pool | ||
module.exports.PoolError = PoolError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting Pool
on itself doesn’t feel right pre-ESM, and it’s not easy to use via pg. Would this even need to be exported with non-colliding error codes like ERR_PG_POOL_…
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean: replacing PoolError
by constants (for instance ERR_PG_POOL_CONNECT_TIMEOUT
, ERR_PG_POOL_UNEXPECTED_CONDITION
, ...) ?
My goal was to implement the same kind of structure than NoticeOrError
interface from pg-protocol
. What would be the PROs/CONs ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe what @charmander is trying to say, is that if, instead of error codes like Z0001
, you used NodeJS like error codes, you would not need to do instanceof PoolError
and you could simply perform a check like:
catch (err) {
if (err.code === 'ERR_PG_POOL_UNEXPECTED_STATE') throw err // something's wrong
else if (err.code === 'ERR_PG_POOL_CONNECTION_TIMEOUT') {} // handle overloaded database
else {} // Probably not a pg-pool error
}
In this case, you would not even need to export PoolError
at all.
Note that because of the way node_modules
are structured, checking for instanceof
might yield false negative in case pg-pool
ends up twice in you node_modules
hierarchy (blame this on NodeJS's ecosystem).
This also explain his other comment explaining that you don't need to explicit every possible error case. ERR_PG_POOL_UNEXPECTED_STATE
+ ERR_PG_POOL_CONNECTION_TIMEOUT
(please find better names 😅) are probably enough.
I believe that his first comment is that this feels right in ESM:
export default Pool
export { Pool, PoolError }
but the following is weird in common-js (pre-ESM)
module.exports = Pool
module.exports.Pool = Pool
because it is the same as doing Pool.Pool = Pool
which feels odd.
If we're going to have custom Error types, it'd be nice to have a single hierarchy for all things pg and PoolError (or maybe "PgPoolError"?) would be a child of a more generic PgError. It makes testing easier too as you can check for a specific type (ex: "PgScramHandshakeError") rather than patterns of message text and have generic error handling for all things DB related in app code. |
Indeed, currently the Having said that, you maybe saw that I'm using the same As a conclusion, I understand the goal of "a single hierarchy for all things pg and PoolError" and I would enjoy to implement it even if I think it's not really required. Could you help us on this @brianc ? |
Co-authored-by: Charmander <~@charmander.me>
Previously the Pool was throwing built-in JS
Error
. It's therefore difficult to identify each kind of error.This patch allow the developer to identify each type of error raised by the Pool with a
PoolError
.Each
PoolError
has its own code and a message (original message for backward compatibility).Codes and errors are documented in README file.