Refactor API error handling and add try-catch blocks

Added try-catch blocks for error handling in API's files to rethrow the errors to the cubit so cubits can update the UI based on them.

Refactored error handling in HTTPInterceptor and HTTPService classes.
This commit is contained in:
Mohammad Salameh
2024-04-15 15:47:13 +03:00
parent dd90a2133f
commit df13c66b1a
9 changed files with 247 additions and 191 deletions

View File

@ -1,18 +1,30 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/features/auth/model/token.dart';
import 'package:syncrow_app/navigation/navigation_service.dart';
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
import 'dart:async';
import 'dart:developer' as developer;
import 'package:syncrow_app/services/api/network_exception.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
class HTTPInterceptor extends InterceptorsWrapper {
@override
List<String> headerExclusionList = [];
List<String> headerExclusionListOfAddedParameters = [
ApiEndpoints.login,
];
@override
void onResponse(Response response, ResponseInterceptorHandler handler) async {
return handler.next(response);
if (await validateResponse(response)) {
super.onResponse(response, handler);
} else {
handler.reject(DioException(
requestOptions: response.requestOptions, response: response));
}
}
@override
@ -20,17 +32,20 @@ class HTTPInterceptor extends InterceptorsWrapper {
RequestOptions options, RequestInterceptorHandler handler) async {
var storage = const FlutterSecureStorage();
var token = await storage.read(key: Token.loginAccessTokenKey);
// options.headers['Authorization'] = 'Bearer $token';
options.headers['Authorization'] = 'Bearer ${'${token!}123'}';
if (checkHeaderExclusionListOfAddedParameters(options.path)) {
options.headers
.putIfAbsent(HttpHeaders.authorizationHeader, () => "Bearer $token");
}
// options.headers['Authorization'] = 'Bearer ${'${token!}123'}';
super.onRequest(options, handler);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) async {
developer.log('Error Message: ${err.message}');
developer.log('Error res Code: ${err.response?.statusCode}');
developer.log('Error res Data: ${err.response?.data}');
developer.log('Error res status message: ${err.response?.statusMessage}');
// developer.log('Error Message: ${err.message}');
// developer.log('Error res Code: ${err.response?.statusCode}');
// developer.log('Error res Data: ${err.response?.data}');
// developer.log('Error res status message: ${err.response?.statusMessage}');
ServerFailure failure = ServerFailure.fromDioError(err);
CustomSnackBar.displaySnackBar(failure.toString());
@ -39,8 +54,8 @@ class HTTPInterceptor extends InterceptorsWrapper {
if (err.response?.statusCode == 401 && token != null) {
await AuthCubit.get(NavigationService.navigatorKey.currentContext!)
.logout();
super.onError(err, handler);
}
super.onError(err, handler);
}
/// Validates the response and returns true if it is successful (status code 2xx).
@ -60,4 +75,15 @@ class HTTPInterceptor extends InterceptorsWrapper {
return false;
}
}
checkHeaderExclusionListOfAddedParameters(String path) {
bool shouldAddHeader = true;
for (var urlConstant in headerExclusionListOfAddedParameters) {
if (path.contains(urlConstant)) {
shouldAddHeader = false;
}
}
return shouldAddHeader;
}
}