TypeError:回调不是通过本地机器的函数(但是在AWS控制台上代码也是如此)

时间:2018-04-05 15:45:15

标签: node.js amazon-web-services npm aws-lambda jest

对于我的高级项目,我正在AWS Lex上实现一个聊天机器人。我已经使用这个确切的代码在AWS控制台中测试了机器人,并且没有任何错误或问题。但是,当我在Node.js中的机器上(而不是在AWS控制台上)编写代码时,我正在尝试通过单元测试运行npm run testnpm test,但我收到以下错误:



FulfillmentCodeHook with no slots
    ✕ Customer asks, 'how can I setup' (12ms)

  ● FulfillmentCodeHook with no slots › Customer asks, 'how can I setup'

    TypeError: callback is not a function

      62 |     var fulfillmentResult = fulfillSetup(processType);
      63 | 
    > 64 |     callback(lexResponses.close(
      65 |       intentRequest.sessionAttributes,
      66 |       fulfillmentResult.fulfillmentState,
      67 |       fulfillmentResult.message
      
      at Object.<anonymous>.module.exports (Chatbot_Processor/SetupProcess_Intent/manageFulfillment.js:64:5)
      at Object.<anonymous>.module.exports (Chatbot_Processor/SetupProcess_Intent/setupProcess.js:29:16)
      at Object.<anonymous> (Tests/setupProcess.spec.js:32:22)
&#13;
&#13;
&#13;

以下是相关的代码段,从handler.js开始,因为这是运行bot时首先调用的文件。

P.S。 constant-vars.js是一个包含所有常量变量列表的文件。我没有把它包括在内。

handler.js

&#13;
&#13;
   'use strict';

const constants = require('./constant-vars');
const dispatch = require('./dispatch');
const assert = require('assert');

exports.handler = (event, context, callback) => {
    try {
        dispatch(event, (response) => {callback(null, response)});
    } catch (err) {
        callback(err);
    }
};
&#13;
&#13;
&#13;

dispatch.js

&#13;
&#13;
'use strict';

const constants = require('./constant-vars');
const setupProcess = require('./SetupProcess_Intent/setupProcess');

module.exports = function(intentRequest, callback) {
    const intentName = intentRequest.currentIntent.name;

    // SetupProcess intent
    if(intentName === constants.SETUP_PROCESS_INTENT) {
        console.log(`${constants.INTENT_TAG} ${intentName}`);
        return setupProcess(intentRequest, callback);
    }
}
&#13;
&#13;
&#13;

setupProcess.js

&#13;
&#13;
'use strict';

const constants = require('../constant-vars');
const handleDialogCodeHook = require('./manageDialogs');
const handleFulfillmentCodeHook = require('./manageFulfillment');
const lexResponses = require('../lexResponses');

module.exports = function(intentRequest, callback) {

    // source of lambda invokation
    const source = intentRequest.invocationSource;

    // source of lambda invokation is Dialog Code Hook
    if(source === constants.DIALOG_CODE_HOOK) {
        return handleDialogCodeHook(intentRequest, callback);
    }

    // source of lambda invokation of Fulfillment Code Hook
    if(source === constants.FULFILL_CODE_HOOK) {
        return handleFulfillmentCodeHook(intentRequest, false, callback);
    }
}
&#13;
&#13;
&#13;

manageFulfillment.js

&#13;
&#13;
'use strict';

const constants = require('../constant-vars');
const lexResponses = require('../lexResponses');

/**
  * builds object for fulfilling SetupProcess intent
  */
function buildFulfillmentResult(fulfillmentState, messageContent) {
  return {
    fulfillmentState,
    message: {
      contentType: 'PlainText',
      content: messageContent
    }
  };
}

/**
  * fulfills SetupProcess intent
  */
function fulfillSetup(processType) {
  
  if(processType === `${constants.AUTO_PAY_SLOT} or ${constants.PAPERLESS_SLOT}`) {
    return buildFulfillmentResult(
      constants.FULFILLED_STATUS,
      constants.SETUP_BOT_RESPONSE.replace('{0}', constants.PROCESSES_LIKE).replace('{1}', processType).replace('{2}', constants.COMPANY_MONTEREY_NUM)
    );
  }

  return buildFulfillmentResult(
    constants.FULFILLED_STATUS,
    constants.SETUP_BOT_RESPONSE.replace('{0}', "").replace('{1}', processType).replace('{2}', constants.COMPANY_MONTEREY_NUM)
  );
}

/**
  * handleFulfillmentCodeHook(intentRequest)
  */
module.exports = function(intentRequest, redirectedFromDialogs = false, callback) {

  // this call to handleFulfillmentCodeHook did not come from the handler for dialog code hook
  if(!redirectedFromDialogs) {
    var processType = intentRequest.currentIntent.slots.processType;
    console.log(`${constants.PROCESS_TYPE_VAL} ${processType}`);

    var fulfillmentResult = fulfillSetup(processType);

    callback(lexResponses.close(
      intentRequest.sessionAttributes,
      fulfillmentResult.fulfillmentState,
      fulfillmentResult.message
      )
    );
  }

  // this call to handleFulfillmentCodeHook came from the handler for dialog code hook,
  // meaning the user did not specify a slot type
  else {
    var processType = `${constants.AUTO_PAY_SLOT} or ${constants.PAPERLESS_SLOT}`;
    var message = constants.SETUP_BOT_RESPONSE.replace('{0}', constants.PROCESSES_LIKE).replace('{1}', processType).replace('{2}', constants.COMPANY_MONTEREY_NUM);
    var fulfillmentResult = buildFulfillmentResult(constants.FULFILLED_STATUS, message);

    callback(lexResponses.close(
      intentRequest.sessionAttributes,
      fulfillmentResult.fulfillmentState,
      fulfillmentResult.message
      )
    );

  }

}
&#13;
&#13;
&#13;

lexResponses.js

&#13;
&#13;
'use strict';

const constants = require('./constant-vars.js');

/**
 * Delegate
 * Directs Amazon Lex to choose the next course of action based on the bot configuration.
 */
module.exports.delegate = function(sessionAttributes, slots) {
    return {
        sessionAttributes,
        dialogAction: {
            type: 'Delegate',
            slots,
        },
    };
}

/**
 * ElicitSlot
 * Informs Amazon Lex that the user is expected to provide a slot value in the response.
 */
module.exports.elicitSlot = function(sessionAttributes, intentName, slots, slotToElicit, message) {
  return {
    sessionAttributes,
    dialogAction: {
      type: 'ElicitSlot',
      intentName,
      slots,
      slotToElicit,
      message
    }
  };
};

/**
 * Close
 * Close dialog with the customer, reporting fulfillmentState of Failed or Fulfilled
 */
module.exports.close =  function(sessionAttributes, fulfillmentState, message) {
    return {
        sessionAttributes,
        dialogAction: {
            type: 'Close',
            fulfillmentState,
            message,
        },
    };
}
&#13;
&#13;
&#13;

0 个答案:

没有答案