Search code examples
javascriptnode.jspromisenode-mysqlrequest-promise

UnhandledPromiseRejectionWarning despite multiple Error checks


I recently have been developing a web app with NODEJS. I have a db model that takes care of all crud operations. Sample DB model

    getDeviceList: function () {
        return new Promise(function (resolve, reject) {
            var sql = "SELECT * FROM `devices`";
            db.query(sql, function (err, result) {
                if (err) {
                    console.log(`FAILED: ${err}`);
                    reject(err);
                } else resolve(result);
            });
        });
    }

And I access this function in DB module like

router.get("/inventory/devices", checkAuth, function (req, res, next) {
    return new Promise(function (resolve, reject) {
        db.getDeviceList().then(function (result) {
            resolve(res.status(200).json(result));
        }).catch(function (err) {
            console.log(`FAILED: ${err}`);
            reject(res.status(200).json(err));
        });
    });
});

Sometimes when I close the DataBase; I get UnhandledPromiseRejectionWarning but In my eyes I am handling all the promises. What is the best way of handling promises and is my method of retrun promise correct? My DB connection block is in app.js

var connection = db.connectDB().then(function (connect) {}).catch(function (err) {
    console.log(`FAILED: ${err}`);
});

and my connectDB() is

function () {
        return new Promise(function (resolve, reject) {
            db = mysql.createPool({
                host: "localhost",
                port: 3306,
                user: "migration",
                password: "iub5015",
                database: "migration"
            });
            db.getConnection(function (err) {
                if (err) {
                    console.log(`FAILED: ${err}`);
                    reject(err);
                } else {
                    console.log("Connected");
                    resolve(db);
                }
            });
        });
    }

Solution

  • The last statement in your catch block,

    reject(res.status(200).json(err));
    

    means that the returned promise is in rejected state. ie the Promise returned by router.get("/inventory/devices", checkAuth, function (req, res, next) is in rejected state and you have missed to catch that. (or express does not catch that as it seems in your case)

    This is why you are getting this UnhandledPromiseRejectionWarning.

    What is the best way of handling promises and is my method of retrun promise correct?

    Well, in my experience it depends. In some scenarios you may want to propagate error by rejecting Promise, or in some case you may just want to handle it some way and return something as resolved value. In your case you may have to look into express docs to figure out how you need to implement promises within your middleware.

    router.get("/inventory/devices", checkAuth, function (req, res, next) {
        return new Promise(function (resolve, reject) {
            db.getDeviceList().then(function (result) {
                resolve(res.status(200).json(result));
            }).catch(function (err) {
                console.log(`FAILED: ${err}`);
                // This will not give UnhandledPromiseRejectionWarning 
                resolve(res.status(500).json(err));
            });
        });
    });