diff --git a/CHANGELOG.md b/CHANGELOG.md index 8801448..0d0f889 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,49 @@ # Changelog +## [2.0.2] - 2024-03-11 + +Overall, these changes primarily revolve around improving exception handling and string formatting versatility. + +### Changed - 2.0.2 + +* Exception message handling has been improved for better readability wherein the handler now uses the string representation of exceptions. +* String formatting logic in the CustomEquatable class has been improved to handle null and empty values more gracefully. +* More descriptive messages in place of direct position to parameters of extends ExceptionState calls have been introduced. `class DataXXXXXExceptionState extends ExceptionState` + + v1.x.x + + ```dart + FailureState( + DataNetworkExceptionState( + NetworkException.noInternetConnection, + StackTrace.current, + ), + ), + ``` + + v2.x.x + + ```dart + FailureState( + DataNetworkExceptionState( + message: 'NetworkException.noInternetConnection', + stackTrace: StackTrace.current, + ), + ), + ``` + +### Added - 2.0.2 + +* More specific details about the exceptions including DioException information in the test cases for exception handling. +* `message` to namedProps in DataHttpExceptionState for more detailed logging. + +### Fixed - 2.0.2 + +* An issue with trailing commas in the output string of the CustomEquatable class. + ## [2.0.1] - 2024-03-10 -### Changed +### Changed - 2.0.1 * revert: renamed method direct DioExceptionHandler.callApi to DioExceptionHandler.callApi_ for compatibility v1 because method original use DioExceptionHandler().callApi() diff --git a/example/pubspec.lock b/example/pubspec.lock index c9eab0e..356cbe5 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -103,7 +103,7 @@ packages: path: ".." relative: true source: path - version: "2.0.0" + version: "2.0.2" fake_async: dependency: transitive description: diff --git a/lib/src/exception_handler/dio/exception_handler_dio.dart b/lib/src/exception_handler/dio/exception_handler_dio.dart index e532f45..45322d8 100644 --- a/lib/src/exception_handler/dio/exception_handler_dio.dart +++ b/lib/src/exception_handler/dio/exception_handler_dio.dart @@ -22,7 +22,7 @@ Future> handleHttpGenericParseResponseDio( try { return FailureState( DataHttpExceptionState( - exception: responseParser.exception, + message: responseParser.exception.toString(), httpException: HttpStatus.fromCode(statusCode).exception(), stackTrace: StackTrace.current, ), @@ -30,7 +30,7 @@ Future> handleHttpGenericParseResponseDio( } catch (e) { return FailureState( DataHttpExceptionState( - exception: responseParser.exception, + message: responseParser.exception.toString(), httpException: HttpException( httpStatus: HttpStatus( code: statusCode, diff --git a/lib/src/exception_state/exceptions_state.dart b/lib/src/exception_state/exceptions_state.dart index 75f52bd..da5304a 100644 --- a/lib/src/exception_state/exceptions_state.dart +++ b/lib/src/exception_state/exceptions_state.dart @@ -79,11 +79,14 @@ class DataHttpExceptionState extends ExceptionState { DataHttpExceptionState({ required this.httpException, required StackTrace stackTrace, - Exception? exception, - }) : super(message: httpException.toString(), stackTrace: stackTrace) { + String? message, + }) : super( + message: message ?? '', + stackTrace: stackTrace, + ) { log( 'A $httpException, captured:', - error: exception.toString(), + error: message, stackTrace: stackTrace, name: 'DataHttpExceptionState', ); @@ -92,7 +95,8 @@ class DataHttpExceptionState extends ExceptionState { final HttpException httpException; @override - Map get namedProps => {'httpException': httpException}; + Map get namedProps => + {'httpException': httpException, 'message': message}; } /// [DataNetworkExceptionState] is for handling network-related exceptions diff --git a/lib/src/utils/custom_equatable.dart b/lib/src/utils/custom_equatable.dart index 8c3f12a..bdaae08 100644 --- a/lib/src/utils/custom_equatable.dart +++ b/lib/src/utils/custom_equatable.dart @@ -24,11 +24,13 @@ abstract class CustomEquatable extends Equatable { is ExceptionState || // For internal exception handler. e.value == null) ? '${e.key}: ${e.value}' - : '${e.key}: "${e.value}"', + : e.value != null && e.value != '' + ? '${e.key}: "${e.value}"' + : '', ) .join(', '); - return '$type($propList)'; + return '$type($propList)'.replaceAll('], )', '])'); } Map get namedProps; diff --git a/pubspec.yaml b/pubspec.yaml index 20920a1..2f5276d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: exception_handler description: A Dart package for streamlined API handling and robust exception management in Flutter apps. -version: 2.0.1 +version: 2.0.2 homepage: "https://github.com/andgar2010/exception_handler" environment: diff --git a/test/src/exception_handler/dio/dio_http_response_extension_test.dart b/test/src/exception_handler/dio/dio_http_response_extension_test.dart index 964d962..830090b 100644 --- a/test/src/exception_handler/dio/dio_http_response_extension_test.dart +++ b/test/src/exception_handler/dio/dio_http_response_extension_test.dart @@ -250,7 +250,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)', + 'DataHttpExceptionState(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0, message: "DioException [unknown]: null")', ); }, ); @@ -290,7 +290,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)', + 'DataHttpExceptionState(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0, message: "DioException [bad response]: null")', ); }, ); @@ -323,7 +323,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState(httpException: HttpException [100 Continue])', + 'DataHttpExceptionState(httpException: HttpException [100 Continue], message: "DioException [bad response]: null")', ); }, ); @@ -358,7 +358,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState(httpException: HttpException [300 Multiple Choices])', + 'DataHttpExceptionState(httpException: HttpException [300 Multiple Choices], message: "DioException [bad response]: null")', ); }, ); @@ -391,7 +391,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState(httpException: HttpException [400 Bad Request])', + 'DataHttpExceptionState(httpException: HttpException [400 Bad Request], message: "DioException [bad response]: null")', ); }, ); @@ -424,7 +424,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState(httpException: HttpException [500 Internal Server Error])', + 'DataHttpExceptionState(httpException: HttpException [500 Internal Server Error], message: "DioException [bad response]: null")', ); }, ); @@ -630,7 +630,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)', + 'DataHttpExceptionState>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0, message: "DioException [unknown]: null")', ); }, ); @@ -670,7 +670,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)', + 'DataHttpExceptionState>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0, message: "DioException [bad response]: null")', ); }, ); @@ -703,7 +703,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState>(httpException: HttpException [100 Continue])', + 'DataHttpExceptionState>(httpException: HttpException [100 Continue], message: "DioException [bad response]: null")', ); }, ); @@ -736,7 +736,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState>(httpException: HttpException [300 Multiple Choices])', + 'DataHttpExceptionState>(httpException: HttpException [300 Multiple Choices], message: "DioException [bad response]: null")', ); }, ); @@ -769,7 +769,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState>(httpException: HttpException [400 Bad Request])', + 'DataHttpExceptionState>(httpException: HttpException [400 Bad Request], message: "DioException [bad response]: null")', ); }, ); @@ -802,7 +802,7 @@ void main() { ); expect( result.exception.toString(), - 'DataHttpExceptionState>(httpException: HttpException [500 Internal Server Error])', + 'DataHttpExceptionState>(httpException: HttpException [500 Internal Server Error], message: "DioException [bad response]: null")', ); }, ); diff --git a/test/src/exception_state/exceptions_state_test.dart b/test/src/exception_state/exceptions_state_test.dart index 1f796e6..b3f0bcc 100644 --- a/test/src/exception_state/exceptions_state_test.dart +++ b/test/src/exception_state/exceptions_state_test.dart @@ -52,23 +52,45 @@ void main() { group( 'DataHttpExceptionState', () { - final DataHttpExceptionState dataHttpException = - DataHttpExceptionState( - exception: null, - httpException: HttpStatus.fromCode(401).exception(), - stackTrace: StackTrace.current, - ); - test('should assign the http exception correctly', () { - expect( - dataHttpException.httpException, - equals(const UnauthorizedHttpException()), + group('null message', () { + final DataHttpExceptionState dataHttpException = + DataHttpExceptionState( + message: null, + httpException: HttpStatus.fromCode(401).exception(), + stackTrace: StackTrace.current, ); + test('should assign the http exception correctly', () { + expect( + dataHttpException.httpException, + equals(const UnauthorizedHttpException()), + ); + }); + test('should correct toString', () { + expect( + dataHttpException.toString(), + 'DataHttpExceptionState(httpException: HttpException [401 Unauthorized])', + ); + }); }); - test('should correct toString', () { - expect( - dataHttpException.toString(), - 'DataHttpExceptionState(httpException: HttpException [401 Unauthorized])', + group('non-null message', () { + final DataHttpExceptionState dataHttpException = + DataHttpExceptionState( + message: 'Error ABC', + httpException: HttpStatus.fromCode(402).exception(), + stackTrace: StackTrace.current, ); + test('should assign the http exception correctly', () { + expect( + dataHttpException.httpException, + equals(const PaymentRequiredHttpException()), + ); + }); + test('should correct toString', () { + expect( + dataHttpException.toString(), + 'DataHttpExceptionState(httpException: HttpException [402 Payment Required], message: "Error ABC")', + ); + }); }); }, );