zuba
zuba

Reputation: 395

ASK error, TypeError: Cannot read property 'type' of undefined

I'm creating a skill that will call back different incidents at different dates and times from a DynamoDB table through Alexa.

My 3 columns are data, time and incident

I've defined my partition and sort key in my Lambda function as

let GetMachineStateIntent = (context, callback) => {    
  var params = {
    TableName: "updatedincident",
    Key: {
        date: "2017-03-21",
        time: "07:38",
        incident: "Blocked Primary",
    }
  };

When I try to test my skill I can't seem to recall the incident correctly, the error I'm getting in Cloudwatch is:

2018-03-28T14:48:53.397Z 042319cb-4a3e-49ae-8b33-1641367107d4 Unexpected error occurred in the skill handler! TypeError: Cannot read property 'type' of undefined at exports.handler.e (/var/task/index.js:70:16)

as well as:

2018-03-28T14:48:53.417Z 042319cb-4a3e-49ae-8b33-1641367107d4 { "errorMessage": "Unexpected error" }

Here is my code from index.js

var AWSregion = 'us-east-1';  // us-east-1
var AWS = require('aws-sdk');
var dbClient = new AWS.DynamoDB.DocumentClient();
AWS.config.update({
    region: "'us-east-1'"
});

let GetMachineStateIntent = (context, callback) => {    
  var params = {
    TableName: "updatedincident",
    Key: {
      date: "2018-03-28",
      time: "04:23",
    }
  };
  dbClient.get(params, function (err, data) {
    if (err) {
       // failed to read from table for some reason..
       console.log('failed to load data item:\n' + JSON.stringify(err, null, 2));
       // let skill tell the user that it couldn't find the data 
       sendResponse(context, callback, {
          output: "the data could not be loaded from your database",
          endSession: false
       });
    } else {
       console.log('loaded data item:\n' + JSON.stringify(data.Item, null, 2));
       // assuming the item has an attribute called "incident"..
       sendResponse(context, callback, {
          output: data.Item.incident,
          endSession: false
       });
    }
  });
};


function sendResponse(context, callback, responseOptions) {
  if(typeof callback === 'undefined') {
    context.succeed(buildResponse(responseOptions));
  } else {
    callback(null, buildResponse(responseOptions));
  }
}

function buildResponse(options) {
  var alexaResponse = {
    version: "1.0",
    response: {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
      },
      shouldEndSession: options.endSession
    }
  };
  if (options.repromptText) {
    alexaResponse.response.reprompt = {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
      }
    };
  }
  return alexaResponse;
}

exports.handler = (event, context, callback) => {
  try {
    var request = event.request;
    if (request.type === "LaunchRequest") {
      sendResponse(context, callback, {
        output: "welcome to my skill. what data are you looking for?",
        endSession: false
      });
  }
    else if (request.type === "IntentRequest") {
      let options = {};         
      if (request.intent.name === "GetMachineStateIntent") {
        GetMachineStateIntent(context, callback);
      } else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
        sendResponse(context, callback, {
          output: "ok. good bye!",
          endSession: true
        });
      }
      else if (request.intent.name === "AMAZON.HelpIntent") {
        sendResponse(context, callback, {
          output: "you can ask me about incidents that have happened",
          reprompt: "what can I help you with?",
          endSession: false
        });
      }
      else {
        sendResponse(context, callback, {
          output: "I don't know that one! please try again!",
          endSession: false
        });
      }
    }
    else if (request.type === "SessionEndedRequest") {
      sendResponse(context, callback, ""); // no response needed
    }
    else {
      // an unexpected request type received.. just say I don't know..
      sendResponse(context, callback, {
          output: "I don't know that one! please try again!",
          endSession: false
      });
    }
  } catch (e) {
    // handle the error by logging it and sending back an failure
    console.log('Unexpected error occurred in the skill handler!', e);
    if(typeof callback === 'undefined') {
       context.fail("Unexpected error");
    } else {
       callback("Unexpected error");
    }
  }
};

and this is my handler GetMachineState.js

function sendResponse(context, callback, responseOptions) {
  if(typeof callback === 'undefined') {
    context.succeed(buildResponse(responseOptions));
  } else {
    callback(null, buildResponse(responseOptions));
  }
}

function buildResponse(options) {
  var alexaResponse = {
    version: "1.0",
    response: {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
      },
      shouldEndSession: options.endSession
    }
  };
  if (options.repromptText) {
    alexaResponse.response.reprompt = {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
      }
    };
  }
  return alexaResponse;
}

exports.handler = (event, context, callback) => {
  try {
    var request = event.request;
    if (request.type === "LaunchRequest") {
      sendResponse(context, callback, {
        output: "welcome to my skill. what do you want to find?",
        endSession: false
      });
    }
    else if (request.type === "IntentRequest") {
      let options = {};         
      if (request.intent.name === "GetMachineStateIntent") {
        // this is where we will wire up the dynamo call
        // for now, just send a simple response and end the session
        sendResponse(context, callback, {
          output: "cinema not implemented yet!",
          endSession: true
        });
      } else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
        sendResponse(context, callback, {
          output: "ok. good bye!",
          endSession: true
        });
      }
      else if (request.intent.name === "AMAZON.HelpIntent") {
        sendResponse(context, callback, {
          output: "you can ask me about incidents that have happened",
          reprompt: "what can I help you with?",
          endSession: false
        });
      }
      else {
        sendResponse(context, callback, {
          output: "I don't know that one! Good bye!",
          endSession: true
        });
      }
    }
    else if (request.type === "SessionEndedRequest") {
      sendResponse(context, callback, ""); // no response needed
    }
    else {
      // an unexpected request type received.. just say I don't know..
      sendResponse(context, callback, {
          output: "I don't know that one! Good bye!",
          endSession: true
      });
    }
  } catch (e) {
    // handle the error by logging it and sending back an failure
    console.log('Unexpected error occurred in the skill handler!', e);
    if(typeof callback === 'undefined') {
       context.fail("Unexpected error");
    } else {
       callback("Unexpected error");
    }
  }
};

Upvotes: 1

Views: 7071

Answers (1)

Mike Dinescu
Mike Dinescu

Reputation: 55720

Its impossible to know for sure if this is the problem or not because you haven't shared the code from the index.js file. The error message you get is telling you that the problem occurs at line 70 in your index.js file so you should look there, and figure out what the problem is.

However, based on the fact that you also posted this as a comment on another question, I'm going to venture to guess that the issue you've run into is that you used the code snippet I provided in the answer to that question and the error is from dereferencing the request.type

You have to make sure the request variable is set to the actual request from the event, like so: var request = event.request where event is provided from exports.handler = (event, context, callback) => {

For example:

exports.handler = (event, context, callback) => {
  var request = event.request;
  if (request.type === "IntentRequest" 
      // make suret the name of the intent matches the one in your interaction model
   && request.intent.name == "GetMachineStateIntent") {
    var dateSlot = request.intent.slots.Date != null ?
                   request.intent.slots.Date.value : "unknown date";
    var timeSlot = request.intent.slots.Time != null ?
                   request.intent.slots.Time.value : "unknown time";

    // respond with speech saying back what the skill thinks the user requested
    sendResponse(context, callback, {
       output: "You wanted the machine state at " 
              + timeSlot + " on " + dateSlot,
       endSession: true
    });
  } else {
    // TODO:  handle other types of requests..
    sendResponse(context, callback, {
       output: "I don't know how to handle this request yet!"
       endSession: true
    }); 
  } 
};

function sendResponse(context, callback, responseOptions) {
  if(typeof callback === 'undefined') {
    context.succeed(buildResponse(responseOptions));
  } else {
    callback(null, buildResponse(responseOptions));
  }
}

function buildResponse(options) {
  var alexaResponse = {
    version: "1.0",
    response: {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
      },
      shouldEndSession: options.endSession
    }
  };
  if (options.repromptText) {
    alexaResponse.response.reprompt = {
      outputSpeech: {
        "type": "SSML",
        "ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
      }
    };
  }
  return alexaResponse;
} 

Upvotes: 1

Related Questions