Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS and pg-promise, catch PostgreSQL exceptions

I'm running NodeJS and pg-promise with a PostgreSQL backend. I've created my own TRIGGER which throws an exception in some cases. Things work fine at this end.

But with pg-promise I have trouble catching the error's name.

Using this code:

...
.catch(function(err) {
    console.log(err);
});

I'm getting the following output:

[ { success: false,
result: 
 { [error: vote_limit_exceeded]
   name: 'error',
   length: 80,
   severity: 'ERROR',
   code: 'P0001',
   detail: undefined,
   hint: undefined,
   position: undefined,
   internalPosition: undefined,
   internalQuery: undefined,
   where: undefined,
   schema: undefined,
   table: undefined,
   column: undefined,
   dataType: undefined,
   constraint: undefined,
   file: 'pl_exec.c',
   line: '3068',
   routine: 'exec_stmt_raise' } } ]

I can see the name 'vote_limit_exceeded' in the context, but how do I return as a text string?

I've tried getting "close" with:

console.log(err[0].result);

But I'm not able to get the 'vote_limit_exceeded' isolated.

like image 363
Michael Nielsen Avatar asked May 16 '16 09:05

Michael Nielsen


1 Answers

This is the standard error presentation by PostgreSQL, which has invisible property message, so calling error.message will give you the expected result.

Best yet is to log your errors like this:

console.log(error.message || error);

Extending on your code example...

It looks like your error context comes from the result of calling batch function. That means in such context you can also call error.getErrors()[0] to get the very first error found.

So for your specific case, a safe error logging would be:

.catch(error => {
    if (Array.isArray(error) && 'getErrors' in error) {
        // the error came from method `batch`;
        // let's log the very first error:
        error = error.getErrors()[0];
    }
    console.log("ERROR:", error.message || error);
});

And of course you can easily change it to log all errors returned by method batch instead.

This question gave me an idea about adding property message to the reject result. There is always a room for improvement ;)

UPDATE

Following this, I updated spex.batch reject implementation to support properties first and message, for easier error handling, and released it as version 0.4.3. The implementation is even better than I initially intended, because both first and message support nested batch results.

If you update pg-promise to version 4.1.10 (or later), then you can log such errors in a generic way:

.catch(error => {
    console.log("ERROR:", error.message || error);
});

It will always log the correct error message, even when the error comes from a nested batch call.

like image 187
vitaly-t Avatar answered Sep 28 '22 09:09

vitaly-t