fix : refresh token Completer in app_interceptor
This commit is contained in:
@@ -4,46 +4,56 @@ import '../../core.dart';
|
|||||||
typedef RefreshTokenCallback = Future<String?> Function();
|
typedef RefreshTokenCallback = Future<String?> Function();
|
||||||
class AppInterceptor extends Interceptor {
|
class AppInterceptor extends Interceptor {
|
||||||
final RefreshTokenCallback refreshTokenCallback;
|
final RefreshTokenCallback refreshTokenCallback;
|
||||||
|
Completer<String?>? _refreshCompleter;
|
||||||
|
|
||||||
AppInterceptor({required this.refreshTokenCallback});
|
AppInterceptor({required this.refreshTokenCallback});
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onError(DioException err, ErrorInterceptorHandler handler) async {
|
Future<void> onError(DioException err, ErrorInterceptorHandler handler) async {
|
||||||
if (err.response?.statusCode == 401 && !ApiHandler.isRefreshing) {
|
if (err.response?.statusCode == 401 && !ApiHandler.isRefreshing) {
|
||||||
|
|
||||||
ApiHandler.cancelAllRequests("Token expired - refreshing");
|
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 {
|
try {
|
||||||
final newToken = await refreshTokenCallback();
|
final newToken = await _refreshCompleter!.future;
|
||||||
if (newToken == null) throw Exception("Refresh failed");
|
if (newToken != null) {
|
||||||
|
final opts = err.requestOptions;
|
||||||
|
opts.headers['Authorization'] = 'Bearer $newToken';
|
||||||
|
|
||||||
|
final dio = Dio();
|
||||||
ApiHandler.reset();
|
final cloneReq = await dio.fetch(opts);
|
||||||
|
handler.resolve(cloneReq);
|
||||||
final opts = err.requestOptions;
|
return;
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (_) {
|
||||||
handler.reject(err);
|
handler.reject(err);
|
||||||
} finally {
|
|
||||||
ApiHandler.isRefreshing = false;
|
|
||||||
}
|
}
|
||||||
} else if (err.type == DioExceptionType.cancel) {
|
} else if (err.type == DioExceptionType.cancel) {
|
||||||
|
|
||||||
handler.next(err);
|
handler.next(err);
|
||||||
} else {
|
} else {
|
||||||
handler.next(err);
|
handler.next(err);
|
||||||
|
|||||||
Reference in New Issue
Block a user