admin管理员组

文章数量:1291656

I'm using postgres with knex javascript library to build my sql queries. I want to handle all thrown errors from postgres server, so the way I want to do this is by checking the type of the thrown error.

try {
   // knex query here
} catch(error) {
    if(error instanceof DatabaseError) {
      // handle pg error by checking error.code or something else
      // then send an custom error message to the client
    }

    // handle another error here which is not caused by the postgres server
}

Is there any way to handle the error like this ?

I'm using postgres with knex javascript library to build my sql queries. I want to handle all thrown errors from postgres server, so the way I want to do this is by checking the type of the thrown error.

try {
   // knex query here
} catch(error) {
    if(error instanceof DatabaseError) {
      // handle pg error by checking error.code or something else
      // then send an custom error message to the client
    }

    // handle another error here which is not caused by the postgres server
}

Is there any way to handle the error like this ?

Share Improve this question asked Apr 11, 2021 at 15:08 AZZ_BAZZ_B 4686 silver badges15 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

Catching Knex/DB Errors:

You can use the async/await syntax:

async function() {
    try {
       await knex(/* knex query here*/)
    } catch(error) {
        if(error instanceof DatabaseError) {
          // handle pg error by checking error.code or something else
          // then send an custom error message to the client
        }
        // handle another error here which is not caused by the postgres server
    }

If for some reason you don't want to use that (newer) syntax, you can also chain a .catch ...

knex(/* knex query here*/)
    .then(doWhatever)
    .catch(error => {
         if(error instanceof DatabaseError) { // ...
    });

Alternative you can also use Knex's query-error (https://knexjs/#Interfaces-query-error) ... but personally I've never seen the point when the built-in promise handlers work just fine.

(EDIT) Distinguishing PG Errors From Knex Ones:

If you want to differentiate Knex and PG-specific errors, you can hook up an error-handler to your PG connection directly (bypassing Knex) like so:

function afterCreate(connection, callback) {
  connection.on("error", connectionError);
  callback(null, connection);
}

db.client.pool.config.afterCreate = afterCreate;

If you do that you won't need a error instanceof DatabaseError, because all errors caught by the connection.on will be PG errors.

You might also find this issue thread (where I got that code from) useful: https://github./knex/knex/issues/522, as it features a discussion of error handling in Knex, and specifically handling of underlying DB errors.

(EDIT) But How Can I Distinguish Errors When I Catch Them?

Unfortunately I don't think PG errors don't have a unique prototype (ie. class) or other distinguishing feature. You can see this by looking at an example one (from that thread I linked):

{"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":5432}

As you can see, there's no way to look that and know "that's ing from PostgreSQL", unless you start checking for specific features like code === 'ECONNREFUSED' (there is no isPg: true flag on the error).

And why doesn't Knex just intelligently identify DB errors for us? From that same issue thread:

It is pretty much impossible to create events like redis have for knex because of multitude of different db drivers which doesn't actually support listening for connection errors

-elhigu (Knex team member)

本文标签: javascriptWhat is the proper way to handle Knex pg database errorsStack Overflow