Hey,
It seems like TableStorage might be broken. While MemoryStorage and FileStorage are working fine, when switching to TableStorage the following errors are thrown on the CLI after the first message is being sent to the bot:
Console Error:
$ node -v
v8.9.4
$ node app.js
restify listening to http://[::]:3978
BotFrameworkAdapter.processActivity(): 500 ERROR - StorageError: An error occurred while processing this request.
RequestId:42eb8cb1-9002-0014-16e9-02d663000000
Time:2018-06-13T07:39:06.5854152Z
(node:76997) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): StorageError: An error occurred while processing this request.
RequestId:42eb8cb1-9002-0014-16e9-02d663000000
Time:2018-06-13T07:39:06.5854152Z
botbuilder versions:
"dependencies": {
"botbuilder": "^4.0.0-preview1.2",
"botbuilder-azure": "^4.0.0-preview1.2",
"botbuilder-dialogs": "^4.0.0-preview1.2",
"dotenv": "^6.0.0",
"restify": "^7.1.1"
}
The issue can be reproduced via this code:
const { FileStorage, BotStateSet, BotFrameworkAdapter, ConversationState, UserState, MessageFactory } = require('botbuilder');
const { TableStorage } = require('botbuilder-azure');
const { DialogSet } = require('botbuilder-dialogs');
const restify = require('restify');
let server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log(`${server.name} listening to ${server.url}`);
});
const adapter = new BotFrameworkAdapter({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword
});
//Add state middleware
const storage = new TableStorage({ tableName: 'test123', storageAccountOrConnectionString: 'DefaultEndpointsProtocol=https;AccountName=xxxx;AccountKey=xxxx;EndpointSuffix=core.windows.net' });
// Bot works fine with FileStorage
//const storage = new FileStorage("/Users/csiebler/xyz/storage/");
const conversationState = new ConversationState(storage);
const userState = new UserState(storage);
adapter.use(new BotStateSet(conversationState, userState));
// Listen for incoming requests
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
if (context.activity.type === 'message') {
const state = conversationState.get(context);
const dc = dialogs.createContext(context, state);
// Continue the current dialog if one is currently active
await dc.continue();
// If we do not have a dialog active, start the root dialog
if (!context.responded) {
await dc.begin('RootDialog');
}
}
});
});
const dialogs = new DialogSet();
dialogs.add('RootDialog', [
async function (dc) {
const options = ["Option 1", "Option 2"];
const actions = MessageFactory.suggestedActions(options, "Hello, I'm here to help you with these 2 things! How can I help you?");
await dc.context.sendActivity(actions);
},
async function (dc, result) {
switch (result) {
case "Option 1":
await dc.begin('Option1');
break;
case "Option 2":
await dc.begin('Option2');
break;
default:
await dc.context.sendActivity("Sorry, I don't understand that command. Please choose an option from the list below.");
break;
}
await dc.endAll().begin('RootDialog');
}
]);
dialogs.add('Option1', [
async function (dc, args) {
await dc.context.sendActivity(`This will become the Option1Dialog`);
await dc.end();
}
]);
dialogs.add('Option2', [
async function (dc, args) {
await dc.context.sendActivity(`This will become the Option2Dialog`);
await dc.end();
}
]);
I might be doing something wrong here, but according to the documentation, the code should be working.
Thanks,
Clemens
I'll look into this shortly.
There is no table storage class.
https://github.com/Microsoft/botbuilder-js/tree/master/libraries/botbuilder-azure/src
See this commit that removed the table storage class
https://github.com/Microsoft/botbuilder-js/commit/93c9c0877c640a7340945644e5679e72c864bacc
Up @Stevenic :) What's the alternative? The tutorials have to be updated accordingly :/
@Stevenic @stevengum I understand this was a part of the PR to remove some explicit middleware, but I'm not sure why table storage was completely removed as a state storage option with no alternative, while the other storage options remain. Can we get this put back in, or are you phasing out Azure Table Storage support?
@csiebler we decided from a design perspective to move to supporting blob storage, as we believe supporting blob storage gives you the same functionality as table storage
@sgellock Any reason not to support both? Is it a resource constraint in terms of code maintenance?
If it鈥檚 definitely gone, can we spin it out as a separate community OSS modules?
@sgellock Thanks for the update!
@szul, yes. the decision to reduce our surface area was a big contributor for the change. We'd totally be supportive of the community spinning it out and making it a separate module.