Timeout async/await functions after a few seconds

I created a function to get an Oracle connection using oracledb, but in a few cases, oracledb didn’t throw an exception even if he didn’t get the connection, apparently he’s trying to connect infinitely.

const getConnection = async (): Promise<oracledb.Connection | undefined> => {
  let connection;

  try {
    connection = await oracledb.getConnection({
      user: process.env.DB_LOGIN,
      password: process.env.DB_PASSWORD,
      connectString: process.env.DB_STRING_CONNECTION,
    });
  } catch (err) {
    console.error(err);
  }
  return connection;
};

I saw a few samples using Promise.racing with setTimeout but i couldn’t put it in pratice, my tries always get an UnhandledPromiseRejectionWarning on console so i think it isn’t the correct way.

Can anybody show me an example how to do that?

I’m learning JavaScript/TypeScript, sorry if this is a stupid question, but i really appreciate any help

Thanks in advance.

3 thoughts on “Timeout async/await functions after a few seconds”

  1. Promise.race should work fine if you implement it properly. Race the getConnection against a Promise that resolves (not rejects), and make sure to chain to a .catch.

    const getConnection = (): Promise<oracledb.Connection | undefined> => {
        return Promise.race([
            oracledb.getConnection({
                user: process.env.DB_LOGIN,
                password: process.env.DB_PASSWORD,
                connectString: process.env.DB_STRING_CONNECTION,
            }),
            new Promise((resolve) => { setTimeout(resolve, 5000); })
        ])
            .catch((error) => {
                // this will only be entered into if getConnection rejects (and not if it times out)
                console.log(error);
            })
    };
    
    Reply
  2. It seems you can set a timeout on your connectString:

    With Oracle Client 19c, timeouts can be passed in Easy Connect strings, for example to timeout after 15 seconds: "mydbmachine.example.com/orclpdb1?connect_timeout=15"

    http://oracle.github.io/node-oracledb/doc/api.html#-1595-database-call-timeouts

    Which means you could just as simply construct the string with the timeout:

    connectString: process.env.DB_STRING_CONNECTION + '?connect_timeout=15',
    

    Of course there are much better ways to handle the construction of your string.

    Reply
  3. CertainPerformance’s answer is great, however I would suggest not entangling timeout logic with your function. These are generic things and should be implemented separately from your connection logic.

    const sleep = ms =>
      new Promise(r => setTimeout(r, ms))
    
    const timeout = (p, ms) =>
      Promise.race([
        p,
        new Promise((_, r) => sleep(ms).then(_ => r(Error("timeout"))))
      ])
      
    const fakeConnect = () =>
      sleep(2000).then(_ => "connected!")
    
    
    // Example 1: 500 ms timeout
    timeout(fakeConnect(), 500)
      .then(console.log, console.error)  // Error: timeout
    
      
    // Example 2: 10 second timeout
    timeout(fakeConnect(), 10000)        // connected!
      .then(console.log, console.error)
    Reply

Leave a Comment