0

In my lambda node code, I am trying to make a call to my SQL DB and retrieve my data.

I am using promises and am able to get the data successfully. However, I am not able to implement error handling as per the requirements.

My requirements are that -

  1. At 'function' level, I return response through 1 variable.
  2. Have one catch statement to catch any errors in the Promise Chain
  3. In case of error, include it and send back as a JSON object.

Below is my code:

'use script';
const mysql = require('mysql');
let res, SQL;

module.exports = async (event, context, callback) => {
    const connection = mysql.createConnection ({
        host: process.env.HOST,
        user: process.env.DBUSER,
        password: process.env.DBPASSWORD,
        database: process.env.INSTANCE,
        port: process.env.PORT,
        connectionLimit: process.env.CONNECTION_LIMIT,   
        multipleStatements: false
    });

    SQL = ` SELECT 
                *
            FROM
                supplie
            WHERE
                isActive=1;`;
                    
    await new Promise( (resolve, reject) => {
    
        connection.connect(function (err) {   
                if (err) { console.log(err); }        
        
            connection.query(SQL, (err, result) => {
                console.log(err);
                resolve(result);
            });
        });
    }).then( (result, err ) => {
        {
            res = {
                "statusCode" : 200,
                "body": JSON.stringify(result),
                "headers"  : {
                    "Access-Control-Allow-Origin" : "*"
                }
            };
            return res;   
        }
    }).catch ( err => {
        console.error('Something Went Wrong');
        console.log(err);
        res = {
            "statusCode" : 404,
            "body": JSON.stringify('Something went wrong!'),
            "headers"  : {
                "Access-Control-Allow-Origin" : "*"
            }
        };
        throw err;
    }).finally( () => {
        return new Promise((resolve, reject) => {
            connection.end(error => error ? reject(error) : resolve());
        });
    });
    // returning response to the function
    return res;
};

Below is the logs and output: Response:

{
  "statusCode": 200,
  "headers": {
    "Access-Control-Allow-Origin": "*"
  }
}

Request ID:

"1fc0c996-8e75-4c0d-b9c9-3757db0a4809"

Function logs:
START RequestId: 1fc0c996-8e75-4c0d-b9c9-3757db0a4809 Version: $LATEST
2020-07-22T17:46:21.117Z    1fc0c996-8e75-4c0d-b9c9-3757db0a4809    INFO    Error: ER_NO_SUCH_TABLE: Table 'supplier_svc_db_dev.supplie' doesn't exist
    at Query.Sequence._packetToError (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:47:14)
    at Query.ErrorPacket (/var/task/node_modules/mysql/lib/protocol/sequences/Query.js:79:18)
    at Protocol._parsePacket (/var/task/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/var/task/node_modules/mysql/lib/protocol/Parser.js:433:10)
    at Parser.write (/var/task/node_modules/mysql/lib/protocol/Parser.js:43:10)
    at Protocol.write (/var/task/node_modules/mysql/lib/protocol/Protocol.js:38:16)
    at Socket.<anonymous> (/var/task/node_modules/mysql/lib/Connection.js:88:28)
    at Socket.<anonymous> (/var/task/node_modules/mysql/lib/Connection.js:526:10)
    at Socket.emit (events.js:310:20)
    at addChunk (_stream_readable.js:286:12)
    --------------------
    at Protocol._enqueue (/var/task/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Connection.query (/var/task/node_modules/mysql/lib/Connection.js:198:25)
    at Handshake.<anonymous> (/var/task/helpers/testPromise.js:28:24)
    at Handshake.<anonymous> (/var/task/node_modules/mysql/lib/Connection.js:526:10)
    at Handshake._callback (/var/task/node_modules/mysql/lib/Connection.js:488:16)
    at Handshake.Sequence.end (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Handshake.Sequence.OkPacket (/var/task/node_modules/mysql/lib/protocol/sequences/Sequence.js:92:8)
    at Protocol._parsePacket (/var/task/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/var/task/node_modules/mysql/lib/protocol/Parser.js:433:10)
    at Parser.write (/var/task/node_modules/mysql/lib/protocol/Parser.js:43:10) {
  code: 'ER_NO_SUCH_TABLE',
  errno: 1146,
  sqlMessage: "Table 'supplier_svc_db_dev.supplie' doesn't exist",
  sqlState: '42S02',
  index: 0,
  sql: ' SELECT \n' +
    '                *\n' +
    '            FROM\n' +
    '                supplie\n' +
    '            WHERE\n' +
    '                isActive=1;'
}
END RequestId: 1fc0c996-8e75-4c0d-b9c9-3757db0a4809
REPORT RequestId: 1fc0c996-8e75-4c0d-b9c9-3757db0a4809  Duration: 805.03 ms Billed Duration: 900 ms Memory Size: 1024 MB    Max Memory Used: 74 MB  Init Duration: 142.20 ms    

Expected Output:

    {
        "statusCode" : 404,
        "body": JSON.stringify('Something went wrong!'),
        "headers"  : {
            "Access-Control-Allow-Origin" : "*"
        }
    };

Any help would be appreciated.

Warm Regards, Adi

Aditya P
  • 19
  • 1
  • 9
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Klaycon Jul 22 '20 at 18:16
  • Thanks for the response @Klaycon. I saw that many implementations using try { } catch { } method. I had implemented similar methods before, but now I am trying to re-architect the code to just .then and Promise statement. – Aditya P Jul 22 '20 at 18:29
  • Looking again I think I jumped the gun seeing you assigning things in a .then callback. But I see now you `await` it so this is perfectly valid. The dupe target certainly is not useful for you then, but I admire your politeness. :P – Klaycon Jul 22 '20 at 18:32

1 Answers1

1

You need to reject the promise in case of an error:

connection.query(SQL, (err, result) => {
                if(err) {
                  return reject(err);
                }
                resolve(result);
            });

Also you need to return res inside the catch block instead of re-throwing the error:

.catch ( err => {
        console.error('Something Went Wrong');
        console.log(err);
        res = {
            "statusCode" : 404,
            "body": JSON.stringify('Something went wrong!'),
            "headers"  : {
                "Access-Control-Allow-Origin" : "*"
            }
        };
        return res;
    })
eol
  • 23,236
  • 5
  • 46
  • 64
  • Thanks for the response, eol. I tested this and I got the below response.. It looks like Rejecting the Promise at the 1st function is not invoking the subsequent .then() methods Response: { "errorType": "Error", "errorMessage": "ER_NO_SUCH_TABLE: Table 'supplier_svc_db_dev.supplie' doesn't exist", ... – Aditya P Jul 22 '20 at 18:25
  • You also need to return res inside the catch block instead of re-throwing the error. – eol Jul 22 '20 at 18:28