简体   繁体   中英

What is the proper way to handle Knex pg database errors

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?

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
        }Sorry

        // 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.org/#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.com/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 coming 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM