How to gracefully fail an automatic token refresh
Hi all,
I'm using the CallClient from @azure/communication-calling to pick up on and add functionality to incoming Teams calls for users. When creating the teams CallClient, a 'tokenRefresher' can be assigned which periodically calls the method you assign to it. The method has token refresh logic to keep the CallClient working.
With my token refresh method, it is possible that a new token cannot be generated and no token can be returned. This will cause an ugly error in the tokenRefresher itself, and I fear it may crash my application at some point. Because the tokenRefresher is called outside of my managed code, I also can't add any error handling for it.
Is there a way to gracefully fail the tokenRefresher? From what I could tell the documentation recommends to return 'undefined' when no token can be refreshed. However, this still results in a 'Uncaught (in promise) InvalidTokenError: Invalid token specified: must be a string' error which I can't handle.
I understand that there is an abortSingal parameter that I can use, but this only helps with signaling new behavior outside the tokenRefresher, while I want the tokenRefresher itself to abort without error.
Azure Communication Services
Microsoft Teams Development
-
Sayali-MSFT • 3,456 Reputation points • Microsoft Vendor
2025-01-09T17:21:43.6733333+00:00 @Jeroen H, Thank you for your inquiry about your Teams app development issue!
We are checking the issue. We will get back to you shortly.
-
Sayali-MSFT • 3,456 Reputation points • Microsoft Vendor
2025-01-10T08:12:15.7633333+00:00 Hello @Jeroen H, To gracefully handle the failure of the
tokenRefresher
in theCallClient
from@azure/communication-calling
, you can implement a safeguard within your token refresh method to ensure that it does not return an invalid token orundefined
. Instead, you can handle the error internally and return a valid token or a fallback mechanism.Here is an example of how you can implement such a safeguard in your token refresh method:
async function tokenRefresher() { try { // Replace this with your actual token refresh logic const newToken = await refreshToken(); if (newToken) { return newToken; } else { // Handle the case where no new token is generated console.warn("Failed to refresh token. Returning a placeholder token."); return "placeholder-token"; // Use a valid placeholder token or handle accordingly } } catch (error) { console.error("Error refreshing token:", error); // Return a valid placeholder token or handle the error gracefully return "placeholder-token"; } } // Initialize CallClient with the tokenRefresher const callClient = new CallClient({ tokenRefresher: tokenRefresher, // other parameters });
-
Jeroen H • 40 Reputation points
2025-01-13T08:03:38.9733333+00:00 Hello @Sayali-MSFT , thank you for the reply.
I understand that I can detect the error within my own refresher method, but I don't understand how this would abort the refreshing process, and without unhandled errors by the refresher. If, on refresh error, I return a placeholder token, won't the refresher just accept this and try to refresh again later as normal?
As an alternative, you mention to 'handle accordingly/gracefully', but how? That is exactly what I'm trying to ask with my post. How do I tell the refresher that I want to abort the refreshing process without throwing an error?
Also, what would the consequences be of using a placeholder token? It sounds like the refresher would just accept it and break functionality by using an invalid token.
-
Sayali-MSFT • 3,456 Reputation points • Microsoft Vendor
2025-01-15T09:17:59.7266667+00:00 Hello @Jeroen H,, To abort the refreshing process without throwing an error, you can implement a flag or status check to indicate that the refresh should not proceed.
If you have specific conditions under which you want to abort the token refresh process, you can use theabortSignal
parameter. This will allow you to signal the token refresher to stop attempting to refresh the token in specific scenarios.
For example:bool shouldAbortRefresh = false; try { var result = await RefreshTokenAsync(); if (result == null) { shouldAbortRefresh = true; } } catch (Exception ex) { shouldAbortRefresh = true; } if (shouldAbortRefresh) { // Skip the refresh process Console.WriteLine("Aborting refresh process."); } else { // Continue with the normal process }
Using a placeholder token can lead to invalid authentication states and broken functionality. The system might accept the token but fail during subsequent operations requiring a valid token.
Note:
While using a placeholder token like an empty string will prevent the application from crashing, it's important to ensure that this does not lead to other unexpected behaviors in your application. Adjust the implementation based on your application's specific requirements and behavior.
-
Jeroen H • 40 Reputation points
2025-01-15T12:56:53.25+00:00 Hi @Sayali-MSFT , thanks for the response.
Please tell me: if my tokenrefresh method returns an empty string but also fires the abortSignal, would an error still still be thrown by the higher level tokenrefresher of the callClient itself? -
Laxman Reddy Revuri • 2,620 Reputation points • Microsoft Vendor
2025-01-20T06:55:11.6266667+00:00 Hi @Jeroen H
If your tokenRefresher method returns an empty string while also triggering the abortSignal, the CallClient's token refresher may still throw an error. This occurs because the CallClient requires a valid token, and an empty string does not meet this requirement. Invalid Token Handling- The CallClient expects a valid token.
- Returning an empty string will cause an InvalidTokenError, as the SDK enforces that the token must be a string.
- Abort Signal Behavior
- The abortSignal cancels the refresh operation but does not prevent errors from invalid tokens.
If the token is missing or empty, the CallClient will still throw an error.
1.Ensure your tokenRefresher method provides a valid token or a fallback value instead of an empty string.
2.Catch token retrieval failures and return a fallback token rather than allowing an empty value.
3. If a valid token is unavailable, implement a retry mechanism or log the failure instead of propagating an unhandled exception. -
Sayali-MSFT • 3,456 Reputation points • Microsoft Vendor
2025-01-21T12:35:01.1266667+00:00 Hi @Jeroen H,Could you please confirm if your issue has resolved with above s uggestion or still looking for any help?
-
Jeroen H • 40 Reputation points
2025-01-22T09:14:07.79+00:00 @Sayali-MSFT not really. As I mentioned in my post and comments, I'm looking to gracefully abort the token refresher while in it.
You have given me a few options, like fallback tokens or using the abort signal, but those will still all handle the current refreshToken call incorrectly, either by still causing an initial error or by returning invalid tokens that might break functionality later on.
If it isn't possible to abort the SDK's refresh procedure without raising errors while I'm in it, then please confirm that for me so I can be sure of it. Because right now, I've only received answers that skirt around my problem statement.
-
Sayali-MSFT • 3,456 Reputation points • Microsoft Vendor
2025-02-05T13:16:05.7133333+00:00 @Jeroen H, we will check this with internal team and let you know the update.
-
Laxman Reddy Revuri • 2,620 Reputation points • Microsoft Vendor
2025-02-18T12:04:02.07+00:00 Hi @Jeroen H
Could you please confirm if your issue has resolved or still looking for any help? -
Jeroen H • 40 Reputation points
2025-02-18T15:14:32.3766667+00:00 I have not received an answer from @Sayali-MSFT , who would ask the internal team and I am indeed still looking for help.
-
Laxman Reddy Revuri • 2,620 Reputation points • Microsoft Vendor
2025-02-20T10:30:27.2833333+00:00 Hi @Jeroen Harpe
Currently, there’s no direct way to abort thetokenRefresher
in theCallClient
from@azure/communication-calling
without triggering errors. The SDK requires thetokenRefresher
to return a valid token string. Returningundefined
,null
, or an invalid token causes errors likeInvalidTokenError
. TheabortSignal
is meant to cancel the operation from outside thetokenRefresher
, not within it.To work around this, ensure your
tokenRefresher
always returns a valid token. If a new token isn’t available, consider returning the existing token or implementing a retry mechanism. However, these are workarounds and don’t fully solve the issue of aborting the refresh without errors.For a more definitive solution, consider contacting Azure Communication Services support or opening an issue on their GitHub. This could provide tailored guidance and potentially influence future SDK improvements. In conclusion, while no built-in method exists to gracefully abort the
tokenRefresher
, engaging with support channels may offer alternative solutions or workarounds.
Sign in to comment