I am using node-postgres to query my database and would like to know how to use async/await and handle errors correctly
An example of my use is here with a very simple query
const { Pool } = require('pg');
let config;
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
  config = { connectionString: process.env.DATABASE_URL, ssl: true };
} else {
  config = {
    host: 'localhost',
    user: 'myuser',
    database: 'mydatabase',
  };
}
const pool = new Pool(config);
async function getAllUsers() {
  let response;
  try {
    response = await pool.query('select * FROM users');
  } catch (error) {
    throw error;
  }
  return response.rows;
}
Then in my routes.js I have
app.get('/all_users', async (req, res) => {
  const users = await queries.getAllUsers();
  console.log(users); // returns all users fine
});
This is my understanding so far, but i don't think I am approaching this correctly as when it comes to errors my app will freeze and throw UnhandledPromiseRejectionWarning. So if I provide an incorrect table for example
async function getAllUsers() {
  let response;
  try {
    response = await pool.query('select * FROM notable');
  } catch (error) {
    throw error;
  }
  return response.rows;
}
UnhandledPromiseRejectionWarning: error: relation "notable" does not exist
The app will crash after 30 seconds and I have not handled this error gracefully
Could anyone point out what i am missing here please?
Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don't explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.
Using node-postgres , you will be able to write Node. js programs that can access and store data in a PostgreSQL database. In this tutorial, you'll use node-postgres to connect and query the PostgreSQL (Postgres in short) database. First, you'll create a database user and the database in Postgres.
When an async function or Promise throws an uncaught error, or when the catcher also throws, such as with your
throw error;
this means that the caller of the function will be faced with a rejected Promise to deal with. If you're using await in the caller, then you'll also have to use try/catch in the caller in order to catch the errors properly:
app.get('/all_users', async (req, res) => {
  try {
    const users = await queries.getAllUsers();
    console.log(users);
  } catch(e) {
    // handle errors
  }
});
Another way to resolve the error without having to use try/catch in the consumer would be not to throw the error in your catch:
async function getAllUsers() {
  let response;
  try {
    response = await pool.query('select * FROM users');
    return response.rows;
  } catch (error) {
    // handle error
    // do not throw anything
  }
}
but this will make it harder for the consumer to know when there was an error.
In this particular case, the async/await/try/catch constructions add a lot of syntax noise without much benefit IMO - for the moment, you might consider using plain Promises instead:
const getAllUsers = () => pool.query('select * FROM users')
  .then(response => response.rows);
// and:
app.get('/all_users', (req, res) => {
  queries.getAllUsers()
    .then((users) => {
      console.log(users);
    })
    .catch((err) => {
      // handle errors
    });
});
async and await shines when you have a few .thens that you'd like to look flatter in your code. If there's only one .then, IMO there's not much benefit to transforming it into async/await syntax. Of course, it's up to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With