The alexa sdk doesn't use the Lambda callback. Instead, it uses the old context.(succeed|fail) methods. This works fine in a lot of cases, but dooms a few fairly simple use cases.
For instance, if your skill wants to increment a number every time the user launches the app, and persist in dynamodb, you would try to set an attribute on launch and then maybe do
this.handler.state = "SOME_STATE";
emit(":ask", "Welcome. What is your name?");
this.attributes.invocations = 1
Unless you have saveBeforeResponse
on, this won't call saveState
and so you have to do that yourself. So now we have
this.handler.state = "SOME_STATE";
emit(":ask", "Welcome. What is your name?");
this.attributes.invocations = 1
emit(":saveState", true);
This will not work. Ask will emit(":responseReady")
, which will call context.succeed
, and poof, sucks to suck for your saveState request. It's callback is likely doomed to fail. Your database won't update and you'll be sad. This is extra confusing because you might happen to use a tell instead.
this.handler.state = "SOME_STATE";
emit(":tell", "This is my skill. Goodbye!");
this.attributes.invocations = 1
emit(":saveState", true);
This will appear to work because tell automatically persists, see #8 for a fix for that. However, all you'll see in your database is the state, because you set invocations
after the tell. And of course the callback for saveState is doomed to fail and so you're screwed.
I propose a switch the use callback. You already have a object property for it! I found it in alexa.js
, it's set and everything! But y'all need to use it instead of the context calls.
I am totally open to being wrong about all this, but after several days of testing and hacking I'm pretty sure this is what's going on. If I can get a response here that this is correct I will gladly make the PR for this change.