From 0854519620035f61494b26fa5a63d376873a4a1b Mon Sep 17 00:00:00 2001 From: Abdelaziz Mahdy Date: Tue, 8 Aug 2023 23:05:13 +0300 Subject: [PATCH] Fixing connection error (#1912) ### New Pull Request Checklist - [x] I have read the [Documentation](https://pub.dev/documentation/dio/latest/) - [x] I have searched for a similar pull request in the [project](https://github.com/cfug/dio/pulls) and found none - [x] I have updated this branch with the latest `main` branch to avoid conflicts (via merge from master or rebase) - [x] I have added the required tests to prove the fix/feature I'm adding - [x] I have updated the documentation (if necessary) - [x] I have run the tests without failures - [x] I have updated the `CHANGELOG.md` in the corresponding package ### Additional context and info (if any) fixing https://github.com/cfug/dio/issues/1911 --- dio/CHANGELOG.md | 2 +- dio/lib/src/adapters/io_adapter.dart | 16 +++++--- dio/lib/src/dio_exception.dart | 3 +- dio/test/basic_test.dart | 6 +-- dio/test/stacktrace_test.dart | 58 +++++++++++++--------------- 5 files changed, 40 insertions(+), 45 deletions(-) diff --git a/dio/CHANGELOG.md b/dio/CHANGELOG.md index c31d4bc75..db72361d5 100644 --- a/dio/CHANGELOG.md +++ b/dio/CHANGELOG.md @@ -5,7 +5,7 @@ See the [Migration Guide][] for the complete breaking changes list.** ## Unreleased -*None.* +- Fix failing requests throw `DioException`s with `.unknown` instead of `.connectionError` on `SocketException`. ## 5.3.2 diff --git a/dio/lib/src/adapters/io_adapter.dart b/dio/lib/src/adapters/io_adapter.dart index fe94f3927..65e9ac6cf 100644 --- a/dio/lib/src/adapters/io_adapter.dart +++ b/dio/lib/src/adapters/io_adapter.dart @@ -115,14 +115,18 @@ class IOHttpClientAdapter implements HttpClientAdapter { if (v != null) request.headers.set(k, v); }); } on SocketException catch (e) { - if (!e.message.contains('timed out')) { - rethrow; + if (e.message.contains('timed out')) { + throw DioException.connectionTimeout( + requestOptions: options, + timeout: options.connectTimeout ?? + httpClient.connectionTimeout ?? + Duration.zero, + error: e, + ); } - throw DioException.connectionTimeout( + throw DioException.connectionError( requestOptions: options, - timeout: options.connectTimeout ?? - httpClient.connectionTimeout ?? - Duration.zero, + reason: e.message, error: e, ); } diff --git a/dio/lib/src/dio_exception.dart b/dio/lib/src/dio_exception.dart index 8e45dca6f..8ba2bfa9e 100644 --- a/dio/lib/src/dio_exception.dart +++ b/dio/lib/src/dio_exception.dart @@ -151,13 +151,14 @@ class DioException implements Exception { factory DioException.connectionError({ required RequestOptions requestOptions, required String reason, + Object? error, }) => DioException( type: DioExceptionType.connectionError, message: 'The connection errored: $reason', requestOptions: requestOptions, response: null, - error: null, + error: error, ); /// The request info for the request that throws exception. diff --git a/dio/test/basic_test.dart b/dio/test/basic_test.dart index eabe7b029..e52faeae6 100644 --- a/dio/test/basic_test.dart +++ b/dio/test/basic_test.dart @@ -44,11 +44,7 @@ void main() { throwsA( allOf([ isA(), - (DioException e) => - e.type == - (isWeb - ? DioExceptionType.connectionError - : DioExceptionType.unknown), + (DioException e) => e.type == (DioExceptionType.connectionError), if (!isWeb) (DioException e) => e.error is SocketException, ]), ), diff --git a/dio/test/stacktrace_test.dart b/dio/test/stacktrace_test.dart index 903383cc0..df479ea22 100644 --- a/dio/test/stacktrace_test.dart +++ b/dio/test/stacktrace_test.dart @@ -205,64 +205,58 @@ void main() async { }, testOn: '!browser', ); - - group('DioExceptionType.unknown', () { + group('DioExceptionType.connectionError', () { test( - JsonUnsupportedObjectError, + 'SocketException on request', () async { - final dio = Dio()..options.baseUrl = 'https://does.not.exist'; - + final dio = Dio() + ..options.baseUrl = 'https://does.not.exist' + ..httpClientAdapter = IOHttpClientAdapter(); await expectLater( - dio.get( - '/test', - options: Options(contentType: Headers.jsonContentType), - data: Object(), - ), + dio.get('/test', data: 'test'), throwsA( allOf([ isA(), - (DioException e) => e.type == DioExceptionType.unknown, - (DioException e) => e.error is JsonUnsupportedObjectError, - (DioException e) => e.stackTrace + (e) => e.type == DioExceptionType.connectionError, + (e) => e.error is SocketException, + (e) => (e.error as SocketException) + .message + .contains("Failed host lookup: 'does.not.exist'"), + (e) => e.stackTrace .toString() .contains('test/stacktrace_test.dart'), ]), ), ); }, - testOn: '!browser', + testOn: 'vm', ); - + }); + group('DioExceptionType.unknown', () { test( - 'SocketException on request', + JsonUnsupportedObjectError, () async { - final dio = Dio() - ..options.baseUrl = 'https://does.not.exist' - ..httpClientAdapter = IOHttpClientAdapter( - createHttpClient: () { - final client = MockHttpClient(); - when(client.openUrl(any, any)).thenThrow( - SocketException('test'), - ); - return client; - }, - ); + final dio = Dio()..options.baseUrl = 'https://does.not.exist'; await expectLater( - dio.get('/test', data: 'test'), + dio.get( + '/test', + options: Options(contentType: Headers.jsonContentType), + data: Object(), + ), throwsA( allOf([ isA(), - (e) => e.type == DioExceptionType.unknown, - (e) => e.error is SocketException, - (e) => e.stackTrace + (DioException e) => e.type == DioExceptionType.unknown, + (DioException e) => e.error is JsonUnsupportedObjectError, + (DioException e) => e.stackTrace .toString() .contains('test/stacktrace_test.dart'), ]), ), ); }, - testOn: 'vm', + testOn: '!browser', ); test(