Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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<TModel> 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()

Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ packages:
path: ".."
relative: true
source: path
version: "2.0.0"
version: "2.0.2"
fake_async:
dependency: transitive
description:
Expand Down
4 changes: 2 additions & 2 deletions lib/src/exception_handler/dio/exception_handler_dio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ Future<ResultState<TModel>> handleHttpGenericParseResponseDio<Response, TModel>(
try {
return FailureState(
DataHttpExceptionState<TModel>(
exception: responseParser.exception,
message: responseParser.exception.toString(),
httpException: HttpStatus.fromCode(statusCode).exception(),
stackTrace: StackTrace.current,
),
);
} catch (e) {
return FailureState(
DataHttpExceptionState<TModel>(
exception: responseParser.exception,
message: responseParser.exception.toString(),
httpException: HttpException(
httpStatus: HttpStatus(
code: statusCode,
Expand Down
12 changes: 8 additions & 4 deletions lib/src/exception_state/exceptions_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,14 @@ class DataHttpExceptionState<TModel> extends ExceptionState<TModel> {
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',
);
Expand All @@ -92,7 +95,8 @@ class DataHttpExceptionState<TModel> extends ExceptionState<TModel> {
final HttpException httpException;

@override
Map<String, Object?> get namedProps => {'httpException': httpException};
Map<String, Object?> get namedProps =>
{'httpException': httpException, 'message': message};
}

/// [DataNetworkExceptionState] is for handling network-related exceptions
Expand Down
6 changes: 4 additions & 2 deletions lib/src/utils/custom_equatable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Object?> get namedProps;
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<UserModel>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)',
'DataHttpExceptionState<UserModel>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0, message: "DioException [unknown]: null")',
);
},
);
Expand Down Expand Up @@ -290,7 +290,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<UserModel>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)',
'DataHttpExceptionState<UserModel>(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")',
);
},
);
Expand Down Expand Up @@ -323,7 +323,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<UserModel>(httpException: HttpException [100 Continue])',
'DataHttpExceptionState<UserModel>(httpException: HttpException [100 Continue], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -358,7 +358,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<UserModel>(httpException: HttpException [300 Multiple Choices])',
'DataHttpExceptionState<UserModel>(httpException: HttpException [300 Multiple Choices], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -391,7 +391,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<UserModel>(httpException: HttpException [400 Bad Request])',
'DataHttpExceptionState<UserModel>(httpException: HttpException [400 Bad Request], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -424,7 +424,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<UserModel>(httpException: HttpException [500 Internal Server Error])',
'DataHttpExceptionState<UserModel>(httpException: HttpException [500 Internal Server Error], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -630,7 +630,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)',
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0, message: "DioException [unknown]: null")',
);
},
);
Expand Down Expand Up @@ -670,7 +670,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [0 unknown_HttpStatus]: exception: Invalid argument (code): Unrecognized status code. Use the HttpStatus constructor for custom codes: 0)',
'DataHttpExceptionState<List<UserModel>>(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")',
);
},
);
Expand Down Expand Up @@ -703,7 +703,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [100 Continue])',
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [100 Continue], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -736,7 +736,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [300 Multiple Choices])',
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [300 Multiple Choices], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -769,7 +769,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [400 Bad Request])',
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [400 Bad Request], message: "DioException [bad response]: null")',
);
},
);
Expand Down Expand Up @@ -802,7 +802,7 @@ void main() {
);
expect(
result.exception.toString(),
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [500 Internal Server Error])',
'DataHttpExceptionState<List<UserModel>>(httpException: HttpException [500 Internal Server Error], message: "DioException [bad response]: null")',
);
},
);
Expand Down
50 changes: 36 additions & 14 deletions test/src/exception_state/exceptions_state_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,45 @@ void main() {
group(
'DataHttpExceptionState',
() {
final DataHttpExceptionState<String> dataHttpException =
DataHttpExceptionState<String>(
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<String> dataHttpException =
DataHttpExceptionState<String>(
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<String>(httpException: HttpException [401 Unauthorized])',
);
});
});
test('should correct toString', () {
expect(
dataHttpException.toString(),
'DataHttpExceptionState<String>(httpException: HttpException [401 Unauthorized])',
group('non-null message', () {
final DataHttpExceptionState<String> dataHttpException =
DataHttpExceptionState<String>(
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<String>(httpException: HttpException [402 Payment Required], message: "Error ABC")',
);
});
});
},
);
Expand Down