Search code examples
javascriptsqlnode.jsaws-lambda

How do I do sql queries with nodejs in AWS lambda?


exports.handler = async (event) => {
    const sql = require('mssql');
    
    let config = {
        user: "MyUsername",
        password: "MyPassword",
        server: "MyServer",
        port: 1433,
        options: {
            database: 'MyDatabase',
            encrypt: false,
        }
    };


    sql.connect(config, (err) => {
        if (err) { console.log(err);}
        else {
            console.log('connected');

            let request = new sql.Request();
            const theQuery = "SELECT * FROM MyTable";

            request.query(theQuery, (err, data)=> {
                if(err) { console.log(err); }
                else { console.log(data); }
            })
       }
    });
};

I am trying to do a simple SELECT query with this, and it seems to work fine when I run it locally, but when I try it on Lambda, it times out. I have the lambda on the same VPC as the SQL Server so it is not a connection issue. Any Ideas?

2022-07-17T03:10:02.912Z    a4775342-517a-4511-920e-46269ee07627    INFO    ConnectionError: Failed to connect to ********:1433 in 15000ms
    at /opt/nodejs/node_modules/mssql/lib/tedious/connection-pool.js:70:17
    at Connection.onConnect (/opt/nodejs/node_modules/tedious/lib/connection.js:1051:9)
    at Object.onceWrapper (node:events:642:26)
    at Connection.emit (node:events:527:28)
    at Connection.emit (node:domain:475:12)
    at Connection.emit (/opt/nodejs/node_modules/tedious/lib/connection.js:1079:18)
    at Connection.connectTimeout (/opt/nodejs/node_modules/tedious/lib/connection.js:1284:10)
    at Timeout._onTimeout (/opt/nodejs/node_modules/tedious/lib/connection.js:1229:12)
    at listOnTimeout (node:internal/timers:559:17)
    at processTimers (node:internal/timers:502:7) {
  code: 'ETIMEOUT',
  originalError: ConnectionError: Failed to connect to ********:1433 in 15000ms
      at Connection.connectTimeout (/opt/nodejs/node_modules/tedious/lib/connection.js:1284:26)
      at Timeout._onTimeout (/opt/nodejs/node_modules/tedious/lib/connection.js:1229:12)
      at listOnTimeout (node:internal/timers:559:17)
      at processTimers (node:internal/timers:502:7) {
    code: 'ETIMEOUT',
    isTransient: undefined
  }
}

Solution

  • As it turns out, the script is simply terminating before finishing. To fix this, I had to return a promise

    exports.handler = async (event) => {
    
        const promise = new Promise(function(resolve, reject) {
            
            let sql = require('mssql');
            
            sql.connect(config, (err) => {
                if (err) {
                    reject(err);
                }
                
                else {
                    const request = new sql.Request();
                    
                    const query = "SELECT * FROM MyTable";
                    request.query(query, (err, result) => {
                        if(err) {
                            reject(err);
                        }
                        
                        else {
                            resolve(result);
                        }
                    });
                }
            });
        });
            
        return promise;
    };