Forum Discussion
How To Trigger App Reinstallation
Thanks for the help.
Reproduction steps:
- run the bot
- install the app for a user in personal scope
- stop the running bot
- delete the .notification.localstore.json file (simulates a storage failure or restoring an old backup that doesn't include the user's ConversationReference)
- Run the bot again
- The app still shows as installed in the users team client but interactions can not be processed by the bot because the bot does not see any installations
- Uninstall and reinstall the app for a user in personal scople
- Interactions now work because the .notification.localstore.json files again includes the ConversationReference
Steps 7 is a manual action that the user has to take compared to something I can fix as the developer. I'm looking for a replacement of step 7 that does not inconvenience my users.
Hello @aellington, you can Implement robust error handling and retry mechanisms in your bot's code. If a write operation to the ConversationReferenceStore fails, the bot should retry the operation a few times before giving up.
When issuing a Bot Builder SDK operation, handle Microsoft.Rest.HttpOperationException and check for the status code. If you receive an HTTP 429 Too Many Requests error, perform a retry of the operation with an exponential backoff. This ensures that multiple requests don't introduce collisions on retries.
Use the transient fault handling application block to detect transient exceptions. For example, you can create a class that implements ITransientErrorDetectionStrategy and checks for specific error codes like 429.
Document Link-Rate limiting for bots - Teams | Microsoft Learn
Here is an example of how you can implement error handling and retries in C#:
public class BotSdkTransientExceptionDetectionStrategy : ITransientErrorDetectionStrategy
{
// List of error codes to retry on
List<int> transientErrorStatusCodes = new List<int>() { 429 };
public bool IsTransient(Exception ex)
{
if (ex.Message.Contains("429")) return true;
HttpResponseMessageWrapper? response = null;
if (ex is HttpOperationException httpOperationException)
{
response = httpOperationException.Response;
}
else if (ex is ErrorResponseException errorResponseException)
{
response = errorResponseException.Response;
}
return response != null && transientErrorStatusCodes.Contains((int)response.StatusCode);
}
}