Open yehorh opened 7 months ago
It seems I have broken the interface contract. I have overridden synchronous functions with asynchronous functions.
The override_on_non_overriding_member
lint hasn't helped me this time.
the same problem is happening with our project too.
We're currently experiencing the same issue using the following interactor to refresh an access token and retry the request, using Dio v5.4.3+1. The request never finishes executing and no exceptions are caught in the try/catch block.
try {
final body = {...};
final options = Options(extra: {'authenticated': true}, validateStatus: (status) => status == 200);
final response = await _dio.post('...', data: body, options: options);
// We never get here
} on DioException catch (error, trace) {
// We never get here
}
class AuthInterceptor extends Interceptor {
final Dio _dio;
final Future<String?> Function() _getAccessToken;
AuthInterceptor({
required Dio dio,
required Future<String?> Function() getAccessToken,
}) : _dio = dio,
_getAccessToken = getAccessToken;
@override
Future<void> onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
// If the request is not authenticated, continue without adding the Authorization header
if (options.extra['authenticated'] == false) {
return handler.next(options);
}
// Try to retrieve a valid (non-expired) access token for the Authorization header.
// If no token could be retrieved, we don't add the header.
final String? accessToken = await _getAccessToken();
if (accessToken != null) {
options.headers['Authorization'] = 'Bearer $accessToken';
}
// Continue request
return handler.next(options);
}
@override
FutureOr<void> onError(DioException error, ErrorInterceptorHandler handler) async {
final Response? response = error.response;
// We're only interested in handling the 401 header here. Let other errors pass through.
if (response == null || response.statusCode != 401) {
return handler.next(error);
}
final RequestOptions options = response.requestOptions;
// If the request was already retried we back off and let the error pass through.
if (options.extra['retried'] == true) {
return handler.next(error); // also tried handler.reject(error) with same result
}
// Add flag to indicate that we retried the request, to prevent infinite retries.
options.extra['retried'] = true;
// Retry the request. A refresh token will be added to the request in the [onRequest]
// handler, when available.
return handler.resolve(await _dio.fetch(options));
}
}
@sdgroot
is this part from your code using the same _dio
instance as the main app thread (final response = await _dio.post('...', data: body, options: options);
?
// Retry the request. A refresh token will be added to the request in the [onRequest]
// handler, when available.
return handler.resolve(await _dio.fetch(options));
for token interceptors it's better to use QueuedInterceptor
and separate Dio instance which do retries, see https://github.com/cfug/dio/blob/main/example/lib/queued_interceptor_crsftoken.dart
@sdgroot
is this part from your code using the same
_dio
instance as the main app thread (final response = await _dio.post('...', data: body, options: options);
?// Retry the request. A refresh token will be added to the request in the [onRequest] // handler, when available. return handler.resolve(await _dio.fetch(options));
for token interceptors it's better to use
QueuedInterceptor
and separate Dio instance which do retries, see https://github.com/cfug/dio/blob/main/example/lib/queued_interceptor_crsftoken.dart
Hi @romandrahan, yes, it was using the same Dio instance as the original request. I've now rewritten my interceptor code according to the example that you posted and that did seem to do the trick, so thank you!
Facing the same issue on my project, do we have any work around for this one.
I solved a similar issue, related to interceptors, downgrading to version 5.4.0, was using 5.4.3+1.
I solved a similar issue, related to interceptors, downgrading to version 5.4.0, was using 5.4.3+1.
@Slexom what was your issue just wondering?
I solved a similar issue, related to interceptors, downgrading to version 5.4.0, was using 5.4.3+1.
@Slexom what was your issue just wondering?
So, basically the interceptors wasn't intercepting at all in iOS 16 (simulator and physical device), built with XCode 15, while working perfectly fine in Android 14 (emulator), Android 13(physical device) and web (chrome). No errors at all from the application logs. Searching for solutions I've reached this issue. Reading the used version was 5.4.1, I've downgraded from 5.4.3+1 to 5.4.0 and this, luckily, solved any issue with iOS.
Please submit reproducible example rather than saying "same issue". The original exception is about mismatched signatures which is not a wide-range behavior.
The original reproducible example can be reproduced since v4 which literally means from the beginning, so anyone who can workaround by downgrading to any version is invalid.
did anyone find any workaround to this other than downgrading the package since i know downgrading the package doesn't work as stated by @AlexV525?
Package
dio
Version
5.4.1
Operating-System
Android
Output of
flutter doctor -v
Dart Version
3.3.1
Steps to Reproduce
Here is a minimal example; I can't understand why the error isn't caught in any way, and everything that follows the request never executes.
tried on Android and macOS
Expected Result
Errors from broken requests must be caught.
Actual Result
The program stops when executing a request, and the subsequent code becomes unreachable.