pg-promise: [Custom Errors] A better way to handle exceptions
First thanks a lot for your library which is amazing and gives off from shit bloated ORM.
One default is about errors handling in our app due to a limitation with the way how you have managed your Error objects inheritance inside your lib.
For instance:
async mutateAndGetPayload(payload, { rootValue: { req, db, cache, conf } }) {
try {
d(payload);
// validation: throws custom errors (an instance extended from Error class) on fail
const res = validator.check(payload, schema);
payload.role = role.BASIC;
payload.status = status.UNREGISTERED;
payload.created_at = payload.updated_at = +new Date;
// throws also
payload.pass = await bcrypt.hashAsync(payload.pass,
conf.BCRYPT_ROUNDS);
// database: throws but a standard Error !!!
return await db.users.insert(payload);
} catch(error) {
// time to handle errors
let messages;
if(error instanceof ValidationError){
messages = validator.messages();
}else if(error instanceof BcryptError){
messages = '...';
}else if(error instanceof DatabaseError){ /* We can't right now pg-promise have not inherited Error */
messages = {
message: error.message,
detail: error.detail,
//...
};
}else{
// messages = ...
}
return messages;
}
},
As you see, your lib only throws standard Errors, error.contructor === Error
and it become very tricky to handle them when many kind of errors from other libs can be thrown by the same try block.
So yeah there is solutions like isolating each portion of code sensitive to throw exception but the code will become messy and unpleasant to ready/follow.
Another way will be to make something like that on the error handler blocks: else if('table' in error && 'constraint' in error) ...
but same problems, the code is ugly and harder to manage.
The clean solution is that you implement a bunch of custom extended Errors inherit from Error class, permitting to use/check them with ease.
if(error instanceof DatabaseConstraintViolationError){
// TODO
}else if(error instanceof DatabaseQueryError){
TODO
}else if(error instanceof DatabaseError /* This is the common parent Error class of your lib */){
// TODO
}
The common parent Error class implementation is important to allow only one check for those do not want check them all.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 19 (11 by maintainers)
There is no error customization in the library. The library provides you with all the error details. All you need is to parse is you you see fit.
I’ve just looked it it, and it seems kind of obsolete.
You can see how this guys just did it, and perhaps do something similar, for the special types of errors that you want to catch: https://github.com/evvvvr/q-and-a/blob/345476b509ad5ffb5e001d4428f583753b7c44d3/src/DbService.js