Files
syncrow-app/lib/services/api/http_interceptor.dart
Mohammad Salameh df13c66b1a 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.
2024-04-15 15:47:13 +03:00

90 lines
3.3 KiB
Dart

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 {
List<String> headerExclusionList = [];
List<String> headerExclusionListOfAddedParameters = [
ApiEndpoints.login,
];
@override
void onResponse(Response response, ResponseInterceptorHandler handler) async {
if (await validateResponse(response)) {
super.onResponse(response, handler);
} else {
handler.reject(DioException(
requestOptions: response.requestOptions, response: response));
}
}
@override
void onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
var storage = const FlutterSecureStorage();
var token = await storage.read(key: Token.loginAccessTokenKey);
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}');
ServerFailure failure = ServerFailure.fromDioError(err);
CustomSnackBar.displaySnackBar(failure.toString());
var storage = const FlutterSecureStorage();
var token = await storage.read(key: Token.loginAccessTokenKey);
if (err.response?.statusCode == 401 && token != null) {
await AuthCubit.get(NavigationService.navigatorKey.currentContext!)
.logout();
}
super.onError(err, handler);
}
/// Validates the response and returns true if it is successful (status code 2xx).
Future<bool> validateResponse(Response response) async {
if (response.statusCode != null) {
if (response.statusCode! >= 200 && response.statusCode! < 300) {
// If the response status code is within the successful range (2xx),
// return true indicating a successful response.
return true;
} else {
// If the response status code is not within the successful range (2xx),
// return false indicating an unsuccessful response.
return false;
}
} else {
// If the response status code is null, return false indicating an unsuccessful response.
return false;
}
}
checkHeaderExclusionListOfAddedParameters(String path) {
bool shouldAddHeader = true;
for (var urlConstant in headerExclusionListOfAddedParameters) {
if (path.contains(urlConstant)) {
shouldAddHeader = false;
}
}
return shouldAddHeader;
}
}