refreshToken method

Future<T> refreshToken({
  1. T? tokenUsedForRequest,
})
inherited

Performs a coordinated token refresh.

If a refresh is already in progress, this will return the same future that the in-flight refresh will complete with. This ensures that concurrent refresh requests result in only one actual refresh operation.

Additionally, if the token has already been refreshed by a previous request (detected by comparing with tokenUsedForRequest), this will return the current token without triggering a new refresh.

The tokenUsedForRequest parameter should be the token value that was used when the request that triggered this refresh was made. This allows detection of cases where another request has already refreshed the token.

If the refresh succeeds, the new token is automatically saved via setToken and returned.

If the refresh fails:

  • If a RevokeTokenException is thrown, clearToken is called and the exception is rethrown.
  • For any other exception, the exception is rethrown without clearing the token.

In all cases (success or failure), the in-flight refresh state is cleared in a finally block, ensuring no deadlocks.

Implementation

Future<T> refreshToken({
  T? tokenUsedForRequest,
}) async {
  // Check if we already have a different token than what was used for the
  // request. This means another request already refreshed the token.
  if (_token != tokenUsedForRequest) {
    // Token has already been refreshed, return the current token
    if (_token != null) {
      return _token as T;
    }
  }

  // If a refresh is already in progress, await it
  final existingFuture = _refreshFuture;
  if (existingFuture != null) {
    return existingFuture;
  }

  // Start a new refresh - create and store the future immediately
  // before any await to prevent race conditions
  final future = _doRefresh();
  _refreshFuture = future;
  return future;
}