fix : refresh token Completer in app_interceptor

This commit is contained in:
2025-06-29 11:55:33 +03:30
parent 1e0eeac1f0
commit 6868e61d5d

View File

@@ -4,46 +4,56 @@ import '../../core.dart';
typedef RefreshTokenCallback = Future<String?> Function();
class AppInterceptor extends Interceptor {
final RefreshTokenCallback refreshTokenCallback;
Completer<String?>? _refreshCompleter;
AppInterceptor({required this.refreshTokenCallback});
@override
Future<void> onError(DioException err, ErrorInterceptorHandler handler) async {
if (err.response?.statusCode == 401 && !ApiHandler.isRefreshing) {
ApiHandler.cancelAllRequests("Token expired - refreshing");
ApiHandler.isRefreshing = true;
if (_refreshCompleter == null) {
_refreshCompleter = Completer<String?>();
ApiHandler.isRefreshing = true;
try {
final newToken = await refreshTokenCallback();
if (newToken == null) throw Exception("Refresh failed");
ApiHandler.reset();
_refreshCompleter?.complete(newToken);
} catch (e) {
_refreshCompleter?.completeError(e);
if (!ApiHandler.isRedirecting) {
ApiHandler.isRedirecting = true;
ApiHandler.cancelAllRequests("Cancel All Requests - Unauthorized");
if (Get.currentRoute != '/Auth') {
Get.offAllNamed('/Auth');
}
}
} finally {
ApiHandler.isRefreshing = false;
_refreshCompleter = null;
}
}
try {
final newToken = await refreshTokenCallback();
if (newToken == null) throw Exception("Refresh failed");
final newToken = await _refreshCompleter!.future;
if (newToken != null) {
final opts = err.requestOptions;
opts.headers['Authorization'] = 'Bearer $newToken';
ApiHandler.reset();
final opts = err.requestOptions;
opts.headers['Authorization'] = 'Bearer $newToken';
final dio = Dio();
final cloneReq = await dio.fetch(opts);
handler.resolve(cloneReq);
return;
} catch (e) {
if (!ApiHandler.isRedirecting) {
ApiHandler.isRedirecting = true;
ApiHandler.cancelAllRequests("Cancel All Requests - Unauthorized");
if (Get.currentRoute != '/Auth') {
Get.offAllNamed('/Auth');
}
final dio = Dio();
final cloneReq = await dio.fetch(opts);
handler.resolve(cloneReq);
return;
}
} catch (_) {
handler.reject(err);
} finally {
ApiHandler.isRefreshing = false;
}
} else if (err.type == DioExceptionType.cancel) {
handler.next(err);
} else {
handler.next(err);