We have developed a chatbot using Azure bot framework. As part of our CI-CD pipeline, we use Sonar Qube to do static code analysis.
Sonar shows multiple instances of code smells as “Redundant use of await on a return value”. The recommendation from Sonar is not to use await as the async method is expected to use a promise.
However, this approach is taken from the BOT Framework samples provided by Microsoft (https://github.com/microsoft/BotBuilder-Samples/blob/main/samples/typescript_nodejs/13.core-bot/src/dialogs/bookingDialog.ts)
Can you please confirm if Microsoft recommendation has changed or this seems to be false positive alert from SonarQube ?
First of all, this Sonar rule was added about 2 years ago in this Pull Request with this example
I then found those SO articles answering similar questions: article 1, article 2 but it was still unclear to me so I kept on looking.
Finally I reviewed this documentation and found the answer I was looking for in the last example provided.
In the above example, notice there is no await statement after the return keyword, although that would be valid too: The return value of an async function is implicitly wrapped in Promise.resolve - if it's not already a promise itself (as in this example).
Note: The implicit wrapping of return values in Promise.resolve does not imply that return await promiseValue is functionally equivalent to return promiseValue.
I tried the error handling with and without the await on my project and ended up removing the await triggering the warning. So far I haven't seen any difference. I have also noticed that if you wrap the same code inside a try / catch, the Sonar warning isn't raised anymore.
From now on, I will follow Sonar's advice but will update this thread if I encounter an issue.
Related
As per the below github issues link for Chatbot and BotFramework.
https://github.com/microsoft/BotFramework-WebChat/issues/1846
We can clear chat history by assigning a new instance to store variable, which triggers a DIRECT_LINE/DISCONNECT action. Now this works in React Webchat. But, I have tried in Web-chat Java script version and the issue seems to still persist, i.e., when the store variable is replaced the previous chats are not removed.
Any confirmation from the community will be relieving as there are many open issues in Botframework github that its confusing. I'm sharing a few that I found out.
https://github.com/microsoft/BotFramework-WebChat/issues/1293
https://github.com/Microsoft/BotFramework-DirectLineJS/issues/124
If No, can this be achieved in some other way? any suggestions will be helpful.
I was able to resolve it. So, just replacing the variable will not work. You need to render the store variable to update/replace it in webchat.js code.
await window.WebChat.renderWebChat(
{
store: widgetStore
},
document.getElementById('webchat')
);
The BotFramework-WebChat repo provides a sample that demonstrates precisely how to do this. The sample is 04.api/h.clear-after-idle. The readme also includes some caveats to be aware of.
I am developing an application using Visual Studio 2019 with code validation.
Some code validation hints are important, however, I am getting a lot of hints in my awaitable method calls, such as
var appUser = await UserManager.FindByIdAsync(User.Identity.GetUserId());
In this case, system is suggesting me to put
var appUser = await UserManager.FindByIdAsync(User.Identity.GetUserId()).ConfigureAwait(true);
or
var appUser = await UserManager.FindByIdAsync(User.Identity.GetUserId()).ConfigureAwait(false);
Is it really necessary to dirty the code in such a way?
This is an MVC5 ASP.NET application.
Regards
Jaime
Is it really necessary to dirty the code in such a way?
If you do not block, then you do not need ConfigureAwait(false).
In the general case, ConfigureAwait(false) is recommended because most code doesn't know whether its callers will block or not. But if this code is part of your application (i.e., not a library), and you're confident your application doesn't block on asynchronous code, then you're fine skipping the ConfigureAwait(false).
Stephen Toub recently published a ConfigureAwait FAQ.
Bot builder comes with LuisRecognizer and other inbuilt classes that does the work of posting the message and getting back the intents and entities.
like replaceDialog helps to start a new waterfall/closure, is there a way to use in built botbuilder classes to post to Luis and based on the match invoke the respective waterfall sequence?
I tried the following.
session.replaceDialog('/'). This does not seem to invoke the luis recognizer again and therefore dialog.matches are not even invoked.
bot.receive(message). this does not do the luis call nor match the intent for the message well. plus, it also seems to go into a wrong sequence ( parent sequence which invokes bot.receive ) again, by default.
IntentDialog.recognize and intentDialog.invokeAction. recognize fails to recognise the message.
What am I doing wrong? is there a way to reuse botbuilder classes?
I can think of writing a simple rest client to invoke Luis api. but that is the last resort, as the purpose of botbuilder's recognizer and intentdialog classes are exactly the same.
flag setting does the trick. Now the modeller gets invoked on every beginDialog.
dialog = new builder.IntentDialog({
recognizeMode : builder.RecognizeMode.onBegin,
});
So far I've tried comparing Parse.Promise, Q and Bluebird but I haven't been able to get an error or catch block to handle/capture an async runtime error.
If you believe that one of the libraries mentioned above, can handle/capture async runtime errors and suspect that I may not have written my sample code correctly, please feel free to point out any mistakes: https://github.com/pulkitsinghal/example-promises
Otherwise I'm looking for suggestions for other promise libraries or frameworks to explore.
It is simply impossible for a library to handle errors beyond its control. The only reason promise libraries are throw safe is because promises use return values to assimilate other promises.
If all your code returns promises instead of callbacks, All A+ promise libraries (that's Q and Bluebird in your example but not Parse.promise) will catch runtime errors and bluebird will even report them automatically without the need to .catch them.
Domains are being deprecated and don't really work well in practice and there is no node-wide solution. Your only option really is to stick to promises app-wide. You must kill and restart the server on an uncaught exception since some parts in node code that throw those do not clean very well after themselves when they throw (this is part of why domains are deprecated to begin with).
So:
Promises are throw safe for runtime errors if you use promises app-wide.
If you have to run untrusted code that might throw consider running it in a VM using the vm module.
Sometimes there are node errors that leave you no choice but to restart a server.
Promisify at the lowest level possible to avoid promisified functions throwing.
Here is a broader question that discusses async error-handling in NodeJS.
I'm using the latest ASP.Net WebAPI Nightly builds (dated 2013-01-16).
I have a simple EF database first model at the moment that has two entities - Patients and Visits. Each patient can have many visits.
I'd like to be able to query for my list of patients and have the visits entities for each patient returned inline. I know that WebAPI's OData implementation doesn't yet support $expand. I'm hoping that just means that optional client-controlled expansion is not supported and that I can force expansion server-side.
At the moment I'm not getting any of the visits inline.
For example, my PatientController's() Get() method looks like
[Queryable(AllowedQueryOptions=AllowedQueryOptions.Supported)]
public override IQueryable<Patient> Get()
{
var query = this.entities.Patients.Include("Visits");
return query;
}
I've verified that the query executing against my database does indeed include the visit information.
To use a publicly available OData service as an example, if you use the service at http://services.odata.org/OData/OData.svc/, you can get a list of Suppliers. This is http://http://services.odata.org/OData/OData.svc/Suppliers.
You can also ask for a list of suppliers that includes the list of products using http://http://services.odata.org/OData/OData.svc/Suppliers?$expand=Products
Stepping through the ASP.NET code (via the symbols server) I've got to the System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer and can see that it's CreatePropertyBag method, which builds up the list of properties to be serialized, just doesn't include the navigation properties, and they don't seem to be enumerated anywhere else apart from being written out as NavigationLinks.
I'm quite new to the ASP.NET world in general and have spent a week or so getting my head around the way things work (particularly with the changes made to OData at the end of 2012 and further changes made so far in 2013).
I suspect that if the ODataEntityTypeSerializer was to be modified (I'm happy to try) to embed this extra information in the appropriate spot (within each navigation link as an nested inline feed as best I can tell) then I'd be set.
Questions:
Have I overlooked something obvious and there's a flag I can set to turn on this behaviour? I can see why, if such a flag exists, it would be off by default (EF lazy loading and this flag wouldn't get on well)
If #1 is no, is there some other ODataEntityTypeSerializer that I could use? If so, how do I switch to it?
If #2 is no, any pointers for where I should start writing my own? Is there a place I can substitute in my own serializer or do I have to maintain my own fork of ASP.NET's Extensions project (as opposed to the Runtime project)
Thanks very much!
$expand is very high on our list of things to support for OData. But as far as I know, we don't have any flag to turn it on server-side. The formatter doesn't currently allow you to substitute your own serializers either. So I'm afraid your only option in the meantime is to create a fork and add support for $expand. If you manage to get it working, please consider sending a pull request our way:
http://aspnetwebstack.codeplex.com/SourceControl/network
You can try it already in webapi nightly builds.
Here is how to install it with nuget:
http://aspnetwebstack.codeplex.com/wikipage?title=Use%20Nightly%20Builds