简体   繁体   English

使用Node.js在Amazon Lambda内部调用REST API的意外行为

[英]Unexpected behavior calling REST API inside Amazon Lambda using Nodejs

I am calling a REST API endpoint inside a lambda function, based on the return value I generate different return objects. 我在lambda函数中调用REST API端点,基于返回值,我生成了不同的返回对象。 The problem I face is when http.request() is called it does not fire the body, end or even error method. 我面临的问题是调用http.request() ,它不会触发正文,结尾甚至错误方法。

Here is my code: 这是我的代码:

var http = require('http');
function getJSON(options, callback){

    http.request(options, function(res){
        var body = "";
        console.log('calling the http');
        res.on('body', function(chunk){
            console.log('body' + chunk);
            body+=chunk;
        });
        res.on('end', function(){
            console.log('end event');    
            var result = JSON.parse(body);
            callback(null, result);
        })

        res.on('error', function(error){
            console.log('Error event');    
            callback('error', callback);
        })
    })
    .on('error', callback)
    .end();    
}

function getCityWeather(cityName, outputSessionAttributes){

    var options = {
        host: `api.openweathermap.org`,
        port: 80,
        path: `/data/2.5/weather?q=${cityName}&appid=api_key_here`,
        method: 'GET'
    };

    getJSON(options, function(err, result){
        if(err){
            console.log(err);
            return buildValidationResult(false, 'TodayWeatherCity', `Invalid city name. Please let me know the city again.`);
        }
        outputSessionAttributes.temprature = result.main.temp;
        console.log(outputSessionAttributes.temprature + ' value');
        return buildValidationResult(true, null, null);
    });

function getWeatherUpdate(intentRequest, callback) {
    const country = intentRequest.currentIntent.slots.TodayWeatherCountry;
    const city = intentRequest.currentIntent.slots.TodayWeatherCity;
    const source = intentRequest.invocationSource;
    const outputSessionAttributes = intentRequest.sessionAttributes || {};

    console.log("outputSessionArribute", intentRequest.sessionAttributes);

    if (source === 'DialogCodeHook') {
        const slots = intentRequest.currentIntent.slots;


        //without promiss implemeation
        var validationResult = getCityWeather(city, outputSessionAttributes);  
        if(!validationResult.isValid) {
            console.log('after calling getCityWeather with result');
            slots[`${validationResult.violatedSlot}`] = null;
            //if response not found then return the invalid city message
            callback(elicitSlot(intentRequest.sessionAttributes, intentRequest.currentIntent.name, slots, validationResult.violatedSlot, validationResult.message));
            return;
        }
        console.log('getWeatherUpdate after calling getCityWeather');
        callback(delegate(outputSessionAttributes, slots));
        return;
    }

    console.log('getWeatherUpdate after DialogCodeHook');
    if(outputSessionAttributes.temprature){

        console.log('getWeatherUpdate inside outputSessionAttributes.temprature return');
        //get the value from the session variable and prompt to user
        callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText',
        content: `Okay, temprature reading for ${city} is ${outputSessionAttributes.temprature}` }));
    }

    //get the value from the session variable and prompt to user
    callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText',
    content: `Sorry, I couldn't server your request` }));
}

When getCityWeather is called it calls getJSON . 调用getCityWeather ,它将调用getJSON But once it calls getJSON only calling the http is printed and function returns error. 但是,一旦调用getJSON仅会打印http ,并且函数将返回错误。

This: 这个:

res.on('body', ...)

Should be this: 应该是这样的:

res.on('data', ...)

Relevant information here : 这里的相关信息:

However, if a 'response' event handler is added, then the data from the response object must be consumed, either by calling response.read() whenever there is a 'readable' event, or by adding a 'data' handler, or by calling the .resume() method. 但是,如果添加了'response'事件处理程序,则必须消耗响应对象中的数据,方法是:在发生'readable'事件时调用response.read() ,或者添加'data'处理程序,或者通过调用.resume()方法。 Until the data is consumed, the 'end' event will not fire. 在使用完数据之前,不会触发'end'事件。 Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error. 同样,在读取数据之前,它将消耗内存,最终可能导致“进程内存不足”错误。

So because you didn't add a data handler, the response stream remains paused. 因此,由于您没有添加data处理程序,因此响应流保持暂停状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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