withAuth<T> method

Future<T> withAuth<T>(
  1. Future<T> call()
)

Executes call with automatic re-authentication on session expiry.

If call fails with a non-DioException error (indicating session expiry or auth failure), this method re-authenticates using stored credentials and retries call once.

Throws NotLoggedInException if no stored credentials are available. Throws InvalidCredentialsException if stored credentials are rejected (credentials are automatically cleared from secure storage). Rethrows DioException from call or re-auth (network errors).

Implementation

Future<T> withAuth<T>(Future<T> Function() call) async {
  try {
    final result = await call();
    _onAuthStatusChanged(AuthStatus.authenticated);
    return result;
  } catch (e) {
    if (e is DioException) {
      _onAuthStatusChanged(AuthStatus.offline);
      rethrow;
    }

    final username = await _secureStorage.read(key: _usernameKey);
    final password = await _secureStorage.read(key: _passwordKey);
    if (username == null || password == null) {
      _onAuthStatusChanged(AuthStatus.credentialsExpired);
      throw NotLoggedInException();
    }

    try {
      await _portalService.login(username, password);
    } on DioException {
      _onAuthStatusChanged(AuthStatus.offline);
      rethrow;
    } catch (_) {
      await _clearCredentials();
      _onAuthStatusChanged(AuthStatus.credentialsExpired);
      throw InvalidCredentialsException();
    }

    _onAuthStatusChanged(AuthStatus.authenticated);
    return await call();
  }
}