| Info | Value | |
| ------------------------------ | ----------------------------------------------------- | ---- |
| Platform Name | e.g. flutter | |
| Platform Version | e.g. master | |
| Dio Version | e.g. 3.0.7 | |
| Android Studio / Xcode Version | e.g. IntelliJ | |
| Repro rate | e.g. all the time (100%) |
| Repro with our demo prj | No | |
I'm using an interceptor with locks to lock the interceptor while a token is being refreshed. If multiple requests are enqueued while the lock is active, once it becomes unlocked, all of the requests run at once, rather than executing sequentially.
I'm having the same issue here. @athornz did you found a solution for this?
Don't stale this issue. It wasn't fixed yet.
Still a problem
I'm having the same issue. :(
Don't state yet
this is very important problem.
please share solution if someone have or alternative package.
I have the same problem. I used the same example as here [https://github.com/flutterchina/dio/issues/50]. When I have few requests with authorization header, every request with invalid token (status 401) do refresh token.
Looks like
dio.interceptor.request.lock();
dio.interceptor.response.lock();
works separately for every request, but not for whole bunch of requests.
I kinda found a work around using static class.
So every request would be statically invoke, not a new instance.
class DioWrapper {
static Dio http = Dio();
static Dio get httpWithoutInterceptors {
return Dio(http.options);
}
static Options defaultCache = buildCacheOptions(
Duration(days: 7),
forceRefresh: true,
);
static bool locked = false; // <---- HERE
static bool get hasToken => (http.options.headers['Authorization'] != null);
static DioCacheManager _cacheManager = DioCacheManager(
CacheConfig(baseUrl: http.options.baseUrl),
);
static InterceptorsWrapper _mainInterceptor = InterceptorsWrapper(
onRequest: (RequestOptions options) async {
return options;
},
onResponse: (Response response) async {
return response;
},
onError: (DioError e) async {
if (e.response != null) {
String $errorMessage = e.response.data['message'];
if (e.response.statusCode == 401) {
if (!locked) {
locked = true; //unlock in AuthModel
Get.snackbar(
'Session Expired',
'Please Login Again!',
duration: Duration(seconds: 10),
);
logout();
}
} else {
Get.defaultDialog(
title: 'Error',
onCancel: () => {},
textCancel: 'Close',
cancelTextColor: Colors.red,
buttonColor: Colors.red,
middleText: $errorMessage,
);
}
return http.reject($errorMessage);
} else {
Get.snackbar(
'Sever Error',
'Please Check Connection!',
duration: Duration(seconds: 10),
);
return http.reject(e.message);
}
},
);
static void setupDioWrapperHttp() {
http.options.headers['X-Requested-With'] = 'XMLHttpRequest';
http.options.baseUrl = 'https://api';
http.interceptors.add(_mainInterceptor);
http.interceptors.add(_cacheManager.interceptor);
http.interceptors.add(LogInterceptor(
request: false,
requestHeader: false,
responseHeader: false,
));
}
static void addTokenHeader(String token) {
http.options.headers['Authorization'] = 'Bearer $token';
}
static Future<void> checkTokenInSharedPreference() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('apiToken');
if (token != null) {
addTokenHeader(token);
}
}
static void logout() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.remove('apiToken');
addTokenHeader(null);
Get.offAllNamed(RouterTable.login);
}
}
main
void main() {
FluroRouter.setupRouter();
DioWrapper.setupDioWrapperHttp();
runApp(HomePage());
}
usage
DioWrapper.http.get(...);
DioWrapper.locked = false;
Yes but, this need to be fixed by the Dio team, and seems that they are not interessed to fix this
Yes but, this need to be fixed by the Dio team, and seems that they are not interessed to fix this
Yes. looks like this package abandoned.
I have the same problem. I used the same example as here [https://github.com//issues/50]. When I have few requests with authorization header, every request with invalid token (status 401) do refresh token.
Looks like
dio.interceptor.request.lock();
dio.interceptor.response.lock();works separately for every request, but not for whole bunch of requests.
First, Please make sure all multiple requests are Initiated by the same one dio instance.
Then, Please check out:
https://github.com/flutterchina/dio/blob/master/example/interceptor_lock.dart
https://github.com/flutterchina/dio/blob/master/dio/test/interceptor_test.dart
multiple requests
Why executing sequential is need? What is the senior ?
If you really need to execute sequentially, you can do this as follows:
// enter `onResponse` one by one
...
onResponse: (){
dio.interceptors.responseLock.lock();
// do anything
...
dio.interceptors.responseLock.unlock();
}
I have the same issue, definitely not fixed in 3.0.10
Most helpful comment
Don't stale this issue. It wasn't fixed yet.