Ошибка тестирования навыка Alexa: Ошибка обработана: Не удается прочитать свойство 'значение' из неопределенного - PullRequest
0 голосов
/ 06 января 2020

Пожалуйста, помогите мне, если какой-либо орган решил проблему, и ниже приведен мой лямбда-код функции. когда я комментирую все функции в функции exports.handler и выполняю / тестирую одну функцию, она работает, но если мы включим все функции, тогда я получаю ошибку как Ошибка обработана: невозможно прочитать свойство 'value' из неопределенного

Node JS code for alexa skill kit for different intents created.

GetNewFactHandler,
    CreateJIRAIssueHandler,
    UpdateJIRAIssueHandler,
    GetJIRAIssueHandler,
    GetJIRAIssueCountHandler,


/* eslint-disable  func-names */
/* eslint-disable  no-console */
var http = require('http');
var https = require('https');

var projectKey='';
var iType='';
var keyValueID='';
var userName='';
var IssueNumber='';

const Alexa = require('ask-sdk');

const GetNewFactHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'LaunchRequest'
      || (request.type === 'IntentRequest'
        && request.intent.name === 'GetNewFactIntent');
  },
  handle(handlerInput) {
    const factArr = data;
    const factIndex = Math.floor(Math.random() * factArr.length);
    const randomFact = factArr[factIndex];
    const speechOutput = GET_FACT_MESSAGE + randomFact;

    return handlerInput.responseBuilder
      .speak(speechOutput)
      .withSimpleCard(SKILL_NAME, randomFact)
      .getResponse();
  },
};


var reqTimeout = 3000;

const CreateJIRAIssueHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        const proKey = request.intent.slots.PROJECTKEY.value;
        const issueType = request.intent.slots.ISSUETYPE.value;
        iType = capitalize_Words(issueType);
        projectKey = proKey.toUpperCase();
        return request.type === 'IntentRequest' &&
            request.intent.name === 'CreateJIRAIssue';
    },
    async handle(handlerInput) {
        const createIssue = await createJiraIssue(projectKey, iType);
        const speechOutput = JSON.parse(createIssue).key;
        return handlerInput.responseBuilder
            .speak('Issue ' + speechOutput + ' created')
            .getResponse();
    },
};

function capitalize_Words(str) {
    return str.replace(/\w\S*/g, function(txt) {
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    });
};

//mule real time server
var muleCreateIssuePath = '/jira/createissue';
var muleProtocol = 'https';
var createIssueMethod = 'POST';
var muleUpdateIssuePath = '/jira/issue/';
var updateIssueMethod = 'PUT';
var getIssueMethod = 'GET';

var MuleReqOpts = {
    host: '',
    port: 443,
    path: undefined, // To be set.
    method: undefined,
    headers: {
        'Content-Type': 'application/json'
    },
    agent: false,
    // auth: jiraUsername + ':' + jiraPassword
    auth: ''

};

var MuleHttp = muleProtocol === 'https' ? https : http;

function createJiraIssue(projectKey, iType) {

    MuleReqOpts.path = muleCreateIssuePath;
    MuleReqOpts.method = createIssueMethod;

    var MuleReqBody = {
        'fields': {
            'project': {
                'key': projectKey
            },
            'summary': 'Test Message',
            'description': 'Issue created for alexa skill kit from Integration alexa to jira',
            'issuetype': {
                'name': iType // Make sure your JIRA project configuration(s) supports this Issue Type.
            }
        }
    };

    return doApiCall(MuleHttp, MuleReqOpts, MuleReqBody, 'creating issue', 201);
};

function doApiCall(httplib, reqOpts, reqBody, happening, successCode) {
    return new Promise(((resolve, reject) => {
        var req = httplib.request(reqOpts, (res) => {
            res.setEncoding('utf8');
            let returnData = '';
            res.on('data', (chunk) => {
                returnData += chunk;
            });
            res.on('end', () => {
                resolve(returnData);
            });
            res.on('error', (error) => {
                reject(error);
            });
        });
        req.write(JSON.stringify(reqBody));
        req.end();

        req.on('error', function(err) {
            context.done(new Error(' request error: ' + err.message));
        });
        req.setTimeout(reqTimeout, function() {
            context.done(new Error(' request timeout after ' + reqTimeout + ' milliseconds.'));
        });
    }));
};

const UpdateJIRAIssueHandler = {

    canHandle(handlerInput) {
            console.log('1');

        const request = handlerInput.requestEnvelope.request;
                    console.log('2');

        userName = request.intent.slots.USER.value;

        var keyValue = request.intent.slots.PROJECTKEY.value;
        console.log('keyValue : ' + keyValue);

        keyValueID = keyValue.toUpperCase();
        IssueNumber = request.intent.slots.ISSUENUMBER.value;
        let INumber = Number(IssueNumber);
            console.log('IssueNumber value: '+INumber);

        console.log('key value id: ' + keyValueID);
        return request.type === 'IntentRequest' &&
            request.intent.name === 'UpdateJIRAIssue';
    },
    async handle(handlerInput) {
        const updateIssue = await updateJiraIssue(userName);
        console.log('updateIssue log: ' + updateIssue);

        const speechOutput = JSON.parse(updateIssue).responseMessage;
        console.log('speechOutput log: ' + speechOutput);
        return handlerInput.responseBuilder
            .speak(speechOutput)
            .getResponse();
    },
};


function updateJiraIssue(userName) {
    console.log('inside method: ' +userName);
    MuleReqOpts.method = updateIssueMethod;

    var postdata = {
        "fields": {
            "assignee": {
                "name": userName
            }
        }
    }

    return doApiUpdateCall(MuleHttp, MuleReqOpts, postdata, 'updating issue', 201);
};

function doApiUpdateCall(httplib, options, postdata, happening, successCode) {

    options.path = muleUpdateIssuePath + keyValueID +'-'+IssueNumber ;

    return new Promise(((resolve, reject) => {

        var req = httplib.request(options, (res) => {
            console.log(options);

            res.setEncoding('utf8');
            let returnData = '';
            res.on('data', (body) => {
                returnData += body;
                console.log(returnData);

            });
            res.on('end', () => {
                resolve(returnData);
            });
            console.log('1');
            console.log('Body: ');
        });

        req.on('error', function(e) {
            console.log('problem with request: ' + e.message);
        });

        var jirapostString = JSON.stringify(postdata);
        console.log(jirapostString);
        req.write(jirapostString);
        req.end();
    }));
};

const GetJIRAIssueHandler = {
    canHandle(handlerInput) {
        console.log('1');
        const request = handlerInput.requestEnvelope.request;
        var keyValue = request.intent.slots.Issue.value;
        console.log('keyValue: ' + keyValue);

        keyValueID = keyValue.toUpperCase();
        return request.type === 'IntentRequest' &&
            request.intent.name === 'GetJIRAIssue';
    },
    async handle(handlerInput) {
        const getIssue = await GetJIRAIssue();
        console.log('getIssue log: ' + getIssue);

        const assigneeName = JSON.parse(getIssue).fields.assignee.name;
        const key = JSON.parse(getIssue).fields.assignee.key;
        const reporterName = JSON.parse(getIssue).fields.reporter.name;
        const issueType = JSON.parse(getIssue).fields.issuetype.name;
        const projectName = JSON.parse(getIssue).fields.project.name;
        const summaryDetails = JSON.parse(getIssue).fields.summary;

        const speechOutput = 'Here are the issue details summary: Assignee : ' + assigneeName.concat(' ,reporter : ' + reporterName, ' ,Issue Key : ' + key, ' ,IssueType : ' + issueType, ' ,ProjectName : ' + projectName, ' ,Summary : ' + summaryDetails);

        console.log('speechOutput log: ' + speechOutput);

        return handlerInput.responseBuilder
            .speak(speechOutput)
            .getResponse();
    },
};


function GetJIRAIssue() {
    MuleReqOpts.method = getIssueMethod;

    return doApiGetIssueCall(MuleHttp, MuleReqOpts, 'get issue details', 201);

};

function doApiGetIssueCall(httplib, options, happening, successCode) {

    options.path = muleUpdateIssuePath + keyValueID;

    return new Promise(((resolve, reject) => {

        https.get(options, (res) => {
            console.log(options);

            res.setEncoding('utf8');
            let returnData = '';
            res.on('data', (body) => {
                returnData += body;
                console.log('response :', returnData);

            });
            res.on('end', () => {
                resolve(returnData);
            });
        });

    }));
};

const GetJIRAIssueCountHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        userName = request.intent.slots.USER.value;
        console.log('userName Value: ' + userName);
        const issueType = request.intent.slots.ISSUETYPE.value;
        iType = capitalize_Words(issueType);
        return request.type === 'IntentRequest' &&
            request.intent.name === 'GetJIRAIssueCount';
    },
    async handle(handlerInput) {
        const getIssueCount = await GetJIRAIssueCount();
        console.log('getIssue log: ' + getIssueCount);
        const total = JSON.parse(getIssueCount).total;

        const speechOutput = ('Here is the '+iType+' count details: ' +total );

        console.log('speechOutput log: ' + speechOutput);

        return handlerInput.responseBuilder
            .speak(speechOutput)
            .getResponse();
    },
};

function GetJIRAIssueCount() {
    MuleReqOpts.method = getIssueMethod;

    return doApiGetIssueCountCall(MuleHttp, MuleReqOpts, 'get issue count details', 201);

};

function doApiGetIssueCountCall(httplib, options, happening, successCode) {

    options.path = muleUpdateIssuePath + userName +'/'+iType;

    return new Promise(((resolve, reject) => {

        https.get(options, (res) => {
            console.log(options);

            res.setEncoding('utf8');
            let returnData = '';
            res.on('data', (body) => {
                returnData += body;
                console.log('response :', returnData);

            });
            res.on('end', () => {
                resolve(returnData);
            });
        });

    }));
};

const HelpHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(HELP_MESSAGE)
      .reprompt(HELP_REPROMPT)
      .getResponse();
  },
};

const ExitHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && (request.intent.name === 'AMAZON.CancelIntent'
        || request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .speak(STOP_MESSAGE)
      .getResponse();
  },
};

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, an error occurred.')
      .reprompt('Sorry, an error occurred.')
      .getResponse();
  },
};

const SKILL_NAME = 'Space Facts';
const GET_FACT_MESSAGE = 'Here\'s your fact: ';
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';

const data = [
  'A year on Mercury is just 88 days long.',
  'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.',
  'Venus rotates counter-clockwise, possibly because of a collision in the past with an asteroid.',
  'On Mars, the Sun appears about half the size as it does on Earth.',
  'Earth is the only planet not named after a god.',
  'Jupiter has the shortest day of all the planets.',
  'The Milky Way galaxy will collide with the Andromeda Galaxy in about 5 billion years.',
  'The Sun contains 99.86% of the mass in the Solar System.',
  'The Sun is an almost perfect sphere.',
  'A total solar eclipse can happen once every 1 to 2 years. This makes them a rare event.',
  'Saturn radiates two and a half times more energy into space than it receives from the sun.',
  'The temperature inside the Sun can reach 15 million degrees Celsius.',
  'The Moon is moving approximately 3.8 cm away from our planet every year.',
];

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    GetNewFactHandler,
    CreateJIRAIssueHandler,
    UpdateJIRAIssueHandler,
    GetJIRAIssueHandler,
    GetJIRAIssueCountHandler,
    HelpHandler,
    ExitHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

Ответы [ 2 ]

1 голос
/ 08 января 2020

Проверьте весь свой код на наличие случаев, когда вы ищете someObject.someNestedProperty.value.

Я подозреваю, что значения ваших слотов в Intents не совпадают с определенными в вашем файле model/some-LANG.json. Попытка получить доступ к свойству value из someObject без someNestedProperty приведет к вашей ошибке (т. Е. request.intent.slots.PROJECTKEY.value).

Если это навык на основе Alexa, встроено ведение журнала CloudWatch. Открыть Консоль разработчика Alexa , измените свое умение, затем go на вкладку Код . В левом нижнем углу вы должны увидеть ссылку для Журналы: Amazon CloudWatch . Вы можете регистрировать все, что захотите, с помощью простого оператора console.log().

Также имейте в виду, что пакет ask-sdk-core npm содержит вспомогательные методы для получения slotValues ​​(среди других замечательных инструментов). Для получения дополнительной информации см. Эту ссылку: https://developer.amazon.com/en-US/docs/alexa/alexa-skills-kit-sdk-for-nodejs/utilities.html

0 голосов
/ 09 января 2020

Спасибо всем за ваши предложения и быстрый ответ. Теперь проблема решена, и решение состоит в том, что метод addRequestHandlers будет выполнять методы последовательно, даже если вы запустите / запустите третий обработчик, он выполнит 1-й и 2-й и перейдет к 3-му. Здесь проблема заключается в том, что когда вы запускаете третью команду обработчика из alexa, она передает значения слотов, относящиеся к 3-му высказыванию обработчика, и, следовательно, 1-й и 2-й халдлер, имеющие значения слотов, не могут быть разрешены и потерпели неудачу. поэтому я поставил условие там, чтобы пропустить выполнение первого и второго обработчиков, и это сработало.

...