简体   繁体   中英

Chaining promises synchronously

I'm working with AWS Lambda. I'm trying to decrypt the key in a async function & then making a POST request to another URL which depends on getting the key first from the first call.

module.exports = function (payload) {
    return new Promise(function(resolve, reject) {
        var headers = config.Headers;
        decrypt(headers.Authorization)
            .then(function (auth_token) {
                headers.Authorization = 'Basic ' + auth_token;
                console.log('dispatch got the key from kms');
                return makePostCall(headers, payload);
            })
             .then(function (changeNumber){
                 console.log(changeNumber);
                 return resolve(changeNumber);
            })
            .catch (function (error) {
                console.error('Error during dispatch: ' + error);
                return reject(error);
            });
    });
};

The decrypt & makePostCall call both return either reject or resolve . Runs fine locally, but when running on Lambda, runs successfully only some times, which led me to believe that issue is with asynchronous calling of the makePostCall function. The error I get(from catch ) is:

Error during dispatch: null

I need to run decrypt first-> Get the key -> then MakePostCall.

Edit: makePostCall looks like this:

function makePostCall(headers, payload) {
    return new Promise(function (resolve, reject) {
        const url = config.serviceNowEndpoint + config.serviceNowChangeUri;
        request.post({
            url: url,
            method: 'POST',
            headers: headers,
            json: payload
        }, function (error, response, body) {
            if (!error) {
                return resolve(body.change_request.number);
            }
            else {
                return reject(new Error('Returned with status code: ' + response.statusCode));
            }
        });
    });
}

More Edit : As per @Jaromanda X 's suggestion, modified the code to:

module.exports = function (payload) {
    var headers = config.Headers;
    return decrypt(headers.Authorization)
        .then(function (auth_token) {
            headers.Authorization = 'Basic ' + auth_token;
            console.log('dispatch got the key from kms');
            return makePostCall(headers, payload);
        })
        .catch (function (error) {
            console.error('Error during dispatch: ' + error);
            return error;
        });
};

Problem still persists though. Runs fine locally, but async on Lambda

Edit adding decrypt code:

const AWS = require('aws-sdk');
const config = require('../config/config');

module.exports = function(token)  {
    return new Promise(function (resolve, reject) {
        const kms = new AWS.KMS({ region: config.aws_region.region});

        const params = {
            CiphertextBlob: new Buffer(token, 'base64')
        };
        kms.decrypt(params, function (err, data) {
            if (!err) {
                console.log('decrypted successfully');
                return resolve(data.Plaintext.toString());
            } else {
                return reject(`${err.message}`);
            }
        });
    });
};

That's an AWS lambda bug. See the issue at Bluebird's repo and basic reproducing code for the issue.

This issue is not actually related to bluebird but to asynchronous code handling and scheduling on lambda's deployment. https://github.com/nervous-systems/cljs-lambda/issues/62 . Here is another issue that reproduces the bug: https://github.com/nervous-systems/cljs-lambda/issues/62 .

A user raises a common issue:

Oh my god. Just in case anyone else lands here and makes my mistake: make sure you haven't accidentally deployed AWS.config.update(...) using a localhost endpoint instead of an actual AWS region-specific endpoint. That can present with similar symptoms as above (say, if the only async function you're using is accessing a DynamoDB document client) but for utterly different reasons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM