From 65f624e9db118642f731999cd610df78d0ba0601 Mon Sep 17 00:00:00 2001 From: Sangam Shrestha <2shrestha22@gmail.com> Date: Wed, 27 Nov 2024 22:48:06 +0545 Subject: [PATCH 1/4] handle http ClientException --- packages/dart/lib/parse_server_sdk.dart | 54 +------------------ .../response/parse_exception_response.dart | 6 +++ 2 files changed, 7 insertions(+), 53 deletions(-) diff --git a/packages/dart/lib/parse_server_sdk.dart b/packages/dart/lib/parse_server_sdk.dart index 3b27e056..dc44313a 100644 --- a/packages/dart/lib/parse_server_sdk.dart +++ b/packages/dart/lib/parse_server_sdk.dart @@ -9,6 +9,7 @@ import 'dart:typed_data'; import 'package:collection/collection.dart'; import 'package:cross_file/cross_file.dart'; import 'package:dio/dio.dart'; +import 'package:http/http.dart'; import 'package:meta/meta.dart'; import 'package:mime/mime.dart'; import 'package:path/path.dart' as path; @@ -29,111 +30,58 @@ export 'src/network/parse_dio_client.dart'; export 'src/network/parse_http_client.dart'; part 'src/base/parse_constants.dart'; - part 'src/data/parse_core_data.dart'; - part 'src/data/parse_subclass_handler.dart'; - part 'src/enums/parse_enum_api_rq.dart'; - part 'src/network/options.dart'; - part 'src/network/parse_client.dart'; - part 'src/network/parse_connectivity.dart'; - part 'src/network/parse_live_query.dart'; - part 'src/network/parse_query.dart'; - part 'src/objects/parse_acl.dart'; - part 'src/objects/parse_array.dart'; - part 'src/objects/parse_base.dart'; - part 'src/objects/parse_cloneable.dart'; - part 'src/objects/parse_config.dart'; - part 'src/objects/parse_error.dart'; - part 'src/objects/parse_exception.dart'; - part 'src/objects/parse_file.dart'; - part 'src/objects/parse_file_base.dart'; - part 'src/objects/parse_file_web.dart'; - part 'src/objects/parse_function.dart'; - part 'src/objects/parse_geo_point.dart'; - part 'src/objects/parse_installation.dart'; - part 'src/objects/parse_number.dart'; - part 'src/objects/parse_object.dart'; - part 'src/objects/parse_operation/parse_add_operation.dart'; - part 'src/objects/parse_operation/parse_add_relation_operation.dart'; - part 'src/objects/parse_operation/parse_add_unique_operation.dart'; - part 'src/objects/parse_operation/parse_increment_operation.dart'; - part 'src/objects/parse_operation/parse_operation.dart'; - part 'src/objects/parse_operation/parse_remove_operation.dart'; - part 'src/objects/parse_operation/parse_remove_relation_operation.dart'; - part 'src/objects/parse_relation.dart'; - part 'src/objects/parse_response.dart'; - part 'src/objects/parse_save_state_aware_child.dart'; - part 'src/objects/parse_session.dart'; - part 'src/objects/parse_user.dart'; - part 'src/objects/parse_x_file.dart'; - part 'src/objects/response/parse_error_response.dart'; - part 'src/objects/response/parse_exception_response.dart'; - part 'src/objects/response/parse_response_builder.dart'; - part 'src/objects/response/parse_response_utils.dart'; - part 'src/objects/response/parse_success_no_results.dart'; - part 'src/storage/core_store.dart'; - part 'src/storage/core_store_memory.dart'; - part 'src/storage/core_store_sem_impl.dart'; - part 'src/storage/xxtea_codec.dart'; - part 'src/utils/parse_date_format.dart'; - part 'src/utils/parse_decoder.dart'; - part 'src/utils/parse_encoder.dart'; - part 'src/utils/parse_live_list.dart'; - part 'src/utils/parse_logger.dart'; - part 'src/utils/parse_login_helpers.dart'; - part 'src/utils/parse_utils.dart'; - part 'src/utils/valuable.dart'; class Parse { diff --git a/packages/dart/lib/src/objects/response/parse_exception_response.dart b/packages/dart/lib/src/objects/response/parse_exception_response.dart index 2450c342..80368ef5 100644 --- a/packages/dart/lib/src/objects/response/parse_exception_response.dart +++ b/packages/dart/lib/src/objects/response/parse_exception_response.dart @@ -22,6 +22,12 @@ ParseResponse buildParseResponseWithException(Exception exception) { )); } + if (exception is ClientException) { + return ParseResponse( + error: ParseError(message: exception.message, exception: exception), + ); + } + return ParseResponse( error: ParseError(message: exception.toString(), exception: exception)); } From dd37a5e5b24998fbc4ac31ed2615ea648d584241 Mon Sep 17 00:00:00 2001 From: Sangam Shrestha <2shrestha22@gmail.com> Date: Sat, 22 Nov 2025 06:50:37 +0545 Subject: [PATCH 2/4] docs: update version and changelog --- packages/dart/CHANGELOG.md | 6 ++++++ packages/dart/pubspec.yaml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/dart/CHANGELOG.md b/packages/dart/CHANGELOG.md index 8fa741e4..64ab61ec 100644 --- a/packages/dart/CHANGELOG.md +++ b/packages/dart/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.0.1](https://github.com/parse-community/Parse-SDK-Flutter/compare/dart-8.0.0...dart-8.0.1) (2025-11-22) + +### Bug Fixes + +* Fix Http client exception not handled properly resulting in incorrectly formatted error ([#1021](https://github.com/parse-community/Parse-SDK-Flutter/pull/1021)) + ## [8.0.0](https://github.com/parse-community/Parse-SDK-Flutter/compare/dart-7.0.1...dart-8.0.0) (2024-12-20) ### BREAKING CHANGES diff --git a/packages/dart/pubspec.yaml b/packages/dart/pubspec.yaml index ae668f69..e9df578f 100644 --- a/packages/dart/pubspec.yaml +++ b/packages/dart/pubspec.yaml @@ -1,6 +1,6 @@ name: parse_server_sdk description: The Dart SDK to connect to Parse Server. Build your apps faster with Parse Platform, the complete application stack. -version: 8.0.0 +version: 8.0.1 homepage: https://parseplatform.org repository: https://github.com/parse-community/Parse-SDK-Flutter issue_tracker: https://github.com/parse-community/Parse-SDK-Flutter/issues From 31cc9806a01eb599f2b0d09c4e0749606c2943c3 Mon Sep 17 00:00:00 2001 From: Sangam Shrestha <2shrestha22@gmail.com> Date: Sun, 23 Nov 2025 21:41:00 +0545 Subject: [PATCH 3/4] fix: safely handle null/non-string errorResponse code --- .../lib/src/objects/response/parse_exception_response.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dart/lib/src/objects/response/parse_exception_response.dart b/packages/dart/lib/src/objects/response/parse_exception_response.dart index 80368ef5..fe66ae1b 100644 --- a/packages/dart/lib/src/objects/response/parse_exception_response.dart +++ b/packages/dart/lib/src/objects/response/parse_exception_response.dart @@ -11,8 +11,9 @@ ParseResponse buildParseResponseWithException(Exception exception) { final errorMessage = errorResponse['error']?.toString() ?? exception.response?.statusMessage; + final String? codeString = errorResponse['code']?.toString(); final errorCode = - int.tryParse(errorResponse['code']) ?? exception.response?.statusCode; + int.tryParse(codeString ?? '') ?? exception.response?.statusCode; return ParseResponse( error: ParseError( From 3d06272634966d13fc966ca1d1449898abf5e57c Mon Sep 17 00:00:00 2001 From: Sangam Shrestha <2shrestha22@gmail.com> Date: Sun, 23 Nov 2025 21:41:16 +0545 Subject: [PATCH 4/4] test: add test for parse exception response --- .../parse_exception_response_test.dart | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 packages/dart/test/src/objects/response/parse_exception_response_test.dart diff --git a/packages/dart/test/src/objects/response/parse_exception_response_test.dart b/packages/dart/test/src/objects/response/parse_exception_response_test.dart new file mode 100644 index 00000000..b57a658b --- /dev/null +++ b/packages/dart/test/src/objects/response/parse_exception_response_test.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:http/http.dart' show ClientException; +import 'package:parse_server_sdk/parse_server_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + group('buildParseResponseWithException', () { + test('parses DioException with JSON body', () { + final response = Response( + requestOptions: RequestOptions(path: '/'), + data: json.encode({'error': 'some error', 'code': '123'}), + statusCode: 400, + statusMessage: 'Bad Request', + ); + + final dioException = DioException( + requestOptions: response.requestOptions, + response: response, + ); + + final result = buildParseResponseWithException(dioException); + + expect(result.error, isNotNull); + expect(result.error!.message, 'some error'); + expect(result.error!.code, 123); + expect(result.error!.exception, dioException); + }); + + test('uses statusMessage and statusCode when body is not JSON', () { + final response = Response( + requestOptions: RequestOptions(path: '/'), + data: 'Not a JSON body', + statusCode: 404, + statusMessage: 'Not Found', + ); + + final dioException = DioException( + requestOptions: response.requestOptions, + response: response, + ); + + final result = buildParseResponseWithException(dioException); + + expect(result.error, isNotNull); + expect(result.error!.message, 'Not Found'); + expect(result.error!.code, 404); + expect(result.error!.exception, dioException); + }); + + test('handles http ClientException', () { + final clientEx = ClientException('no network'); + + final result = buildParseResponseWithException(clientEx); + + expect(result.error, isNotNull); + expect(result.error!.message, 'no network'); + expect(result.error!.exception, clientEx); + }); + + test('handles generic Exception', () { + final ex = Exception('generic'); + + final result = buildParseResponseWithException(ex); + + expect(result.error, isNotNull); + expect(result.error!.message, ex.toString()); + expect(result.error!.exception, ex); + }); + }); +}