-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Package
dio
Version
5.9.0
Operating-System
iOS
Adapter
Default Dio
Output of flutter doctor -v
[✓] Flutter (Channel stable, 3.35.0, on macOS 14.7.1 23H222 darwin-arm64, locale es-ES) [3,4s]
• Flutter version 3.35.0 on channel stable at /Users/javierbustamante/fvm/versions/3.35.0
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision b896255557 (3 months ago), 2025-08-13 17:14:08 -0700
• Engine revision 1e9a811bf8
• Dart version 3.9.0
• DevTools version 2.48.0
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations,
enable-lldb-debugging
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [12,9s]
• Android SDK at /Users/javierbustamante/Library/Android/sdk
• Emulator version 35.2.10.0 (build_id 12414864) (CL:N/A)
• Platform android-36, build-tools 35.0.0
• Java binary at: /Users/javierbustamante/Library/Java/JavaVirtualMachines/jbr-17.0.12/Contents/Home/bin/java
This JDK is specified in your Flutter configuration.
To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment JBR-17.0.12+1-1207.37-nomod (build 17.0.12+1-b1207.37)
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [13,9s]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 16C5032a
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [9ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2024.2) [9ms]
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 21.0.3+-79915917-b509.11)
[✓] VS Code (version 1.104.3) [7ms]
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (3 available) [13,1s]
• iPhone 16 Pro (mobile) • A4547058-A9C0-4194-816F-8EAC302CD150 • ios • com.apple.CoreSimulator.SimRuntime.iOS-18-2 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 14.7.1 23H222 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 142.0.7444.162
! Error: Browsing on the local area network for iPhone de Busta. Ensure the device is unlocked and attached with a cable or associated with
the same local area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources [308ms]
• All expected network resources are available.
! Doctor found issues in 1 category.Dart Version
3.9.0
Steps to Reproduce
I've found a problem with the performance of the QueuedInterceptors.
I have a really complex interceptors distribution so it's easier to describe the problem with an example.
I'd like to clarify that maybe it's no a bug but a lack of clear documentation.
Let's see the case:
To start, I have 4 interceptors (I1, I2, I3, I4) and I passed it to dio with:
instance.interceptors.addAll([I1, I2, I3, I4]);
Each interceptor is a queued inteceptor (beaceause the order of execution is very important) and has different functionality in onResponse and onError.
So the Idea is to chain the Interceptors with the following order:
OutGoing: I1(onRequest) -> I2(onRequest) -> I3(onRequest) -> I4(onRequest)
Incoming: I4(onResponse|onError) -> I3(onResponse|onError) -> I2(onResponse|onError) -> I1(onResponse|onError)
The goal is that each interceptor get the state of the previous one, i.e.: if the onResponse function of I3 returns a handler.reject it has to be followed by the execution of the I2 onError function.
Here comes the problems:
- Actually the outgoing order is good I1(onRequest) -> I2(onRequest) -> I3(onRequest) -> I4(onRequest) but when the call incomes from network I see the same execution order (I1(onRequest) -> I2(onRequest) -> I3(onRequest) -> I4(onRequest)).
- The other problem is that when I execute a handler.reject the call returns an exception directly instead of execute the onError of the next Interceptor.
In order to clarify, that the dummy code for the test:
Test interceptor:
import 'package:dio/dio.dart';
class DioNetTestErrorInterceptor extends QueuedInterceptor {
final String id;
DioNetTestErrorInterceptor(this.id);
@override
void onRequest(
RequestOptions options,
RequestInterceptorHandler handler,
) async {
print('[DioNetTestErrorInterceptor-$id] onRequest');
return handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) async {
print('[DioNetTestErrorInterceptor-$id] onResponse');
if (id == '4') {
final dioError = DioException(
requestOptions: response.requestOptions,
error: 'Fake error',
type: DioExceptionType.badResponse,
response: Response(
requestOptions: response.requestOptions,
statusCode: 500,
data: {"code": 900, "message": "Fake error"},
),
);
return handler.reject(dioError);
} else {
return handler.next(response);
}
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
print('[DioNetTestErrorInterceptor-$id] onError');
return handler.next(err);
}
}
Dio instance creation:
Dio newInstance = Dio(options);
newInstance.interceptors.addAll([
DioNetTestErrorInterceptor(1),
DioNetTestErrorInterceptor(2),
DioNetTestErrorInterceptor(3),
DioNetTestErrorInterceptor(4),
])
Expected Result
Start Call
[DioNetTestErrorInterceptor-1] onRequest
[DioNetTestErrorInterceptor-2] onRequest
[DioNetTestErrorInterceptor-3] onRequest
[DioNetTestErrorInterceptor-4] onRequest
[DioNetTestErrorInterceptor-4] onResponse
[DioNetTestErrorInterceptor-3] onError
[DioNetTestErrorInterceptor-2] onError
[DioNetTestErrorInterceptor-1] onError
End Call
Actual Result
Start Call
[DioNetTestErrorInterceptor-1] onRequest
[DioNetTestErrorInterceptor-2] onRequest
[DioNetTestErrorInterceptor-3] onRequest
[DioNetTestErrorInterceptor-4] onRequest
[DioNetTestErrorInterceptor-1] onResponse
End Call