1

The docs on https://node-postgres.com/guides/async-express give the example of:

const { Pool } = require('pg')
const pool = new Pool()
module.exports = {
  query: (text, params) => pool.query(text, params),
}

My DB code is effectively the same, with some added logging:

const { Pool } = require('pg')

var config = {
  user: process.env.DB_USER,
  database: process.env.DB,
  password: process.env.DB_PASSWORD,
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  max: 10,
  idleTimeoutMillis: 30000,
};

const pool = new Pool(config);
module.exports = {
  query: (text, params) => {
    console.log(`sql: ${text}, params: ${params}`);
    return pool.query(text, params);
  }
}

This works fine when called with:

const result = await db.query('SELECT * FROM users WHERE email = $1 AND password = $2;', 
                              [req.body.email, req.body.password]);

When I make a mistake in my SQL, I get the warning:

(node:6345) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6345) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
POST /verify - - ms - -
post /verify
(node:6345) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'id' of undefined
    at router.post (/home/fadedbee/myapp/routes/index.js:93:58)
    ...
    at router (/home/fadedbee/myapp/node_modules/express/lib/router/index.js:47:12)
(node:6345) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. is what worries me.

How should I change my DB code fix this?

3 Answers 3

2

No functional difference to selfagencies answer, but in regards to the "lots of noise"... The repeated error handling code can be pulled out into a helper that loads your handlers and does any of the common request/response work.

async function myHandler(req, res){ 
  const query = 'SELECT * FROM users WHERE email = $1 AND password = $2;'
  return db.query(query, [ req.body.email, req.body.password ]);
})

function loadRoute(handlerFunction){
  return async function routeLoaderHelper(req, res, next){
    try {
      const res = await handlerFunction(req, res, next)
      // or templatey handling can go here too
      res.json({ data: res })
    }
    catch (error) {
      console.error(error)
      res.status(error.status || 500).json({ error })
    }
  }
}

app.post('/whatever', loadRoute(myHandler))

or use koa, which is the "async" express.

Sign up to request clarification or add additional context in comments.

Comments

1

You need to wrap your await in a try/catch block and handle the error.

const query = 'SELECT * FROM users WHERE email = $1 AND password = $2;';

try {
  const result = await db.query(query, [req.body.email, req.body.password]);
  
  // do something with result
} catch(error) {
  console.error(error)
}

2 Comments

Thanks for your answer. Adding try/catch blocks to dozens of queries is a lot of noise. I assume that I can't add the try/catch inside of query(). Is there a (central) way that I can make express return a 500 if any error is thrown?
You can wrap the entire algorithm in a try/catch and not just the individual db calls, but you're going to have a harder time with specific error handling methods.
0

Running:

npm install express-promise-router --save

and then changing the top of my routes/index.js from:

const express = require('express');
const router = express.Router();

to:

const router = require("express-promise-router")();

Fixed the problem nicely. I now get an error page, with a stack trace during development.

I have not needed to add any try { blocks or wrapper functions.

1 Comment

The express-promise-router wrapper implementation houses the promise rejection handler

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.