diff --git a/lib/networkApiServices/network_api_services.dart b/lib/networkApiServices/network_api_services.dart index 33ceba7..0bde2c2 100644 --- a/lib/networkApiServices/network_api_services.dart +++ b/lib/networkApiServices/network_api_services.dart @@ -20,50 +20,79 @@ class NetworkApiService { }, ), ); + // === RETRY INTERCEPTOR (for timeouts & connection errors) === + _dio.interceptors.add(InterceptorsWrapper( + onError: (DioException err, handler) async { + final options = err.requestOptions; + const maxRetries = 2; // Total attempts = 1 initial + 2 retry + final currentRetry = options.extra['retry'] as int? ?? 0; - // Add interceptors + final shouldRetry = currentRetry < maxRetries && + (err.type == DioExceptionType.connectionTimeout || + err.type == DioExceptionType.sendTimeout || + err.type == DioExceptionType.receiveTimeout ); + if (shouldRetry) { + if (kDebugMode) { + print('🔁 Retrying request (${currentRetry + 1}) to ${options.uri}'); + } + // Wait before retrying + // await Future.delayed(const Duration(seconds: 1)); + options.extra['retry'] = currentRetry + 1; + // Re-execute the request + try { + final response = await _dio.fetch(options); + return handler.resolve(response); + } on DioException catch (e) { + return handler.reject(e); + } + } + // Not retrying → propagate original error + return handler.reject(err); + }, + )); + // === MAIN INTERCEPTOR (logging, auth, etc.) === _dio.interceptors.add( InterceptorsWrapper( onRequest: (options, handler) { - // Add token if available - // String? token = "use token here from local shared preference"; + // Add token if available (uncomment when needed) + // String? token = "your_token_here"; // if (token != null) { // options.headers['Authorization'] = 'Bearer $token'; // } if (kDebugMode) { - print('REQUEST[${options.method}] => URL: ${options.uri}'); + print('📤 REQUEST[${options.method}] => URL: ${options.uri}'); } return handler.next(options); }, onResponse: (response, handler) { if (kDebugMode) { - print('RESPONSE[${response.statusCode}] => DATA: ${response.data}'); + print('📥 RESPONSE[${response.statusCode}] => DATA: ${response.data}'); } return handler.next(response); }, onError: (error, handler) { if (kDebugMode) { - print('ERROR[${error.response?.statusCode}] => MESSAGE: ${error.message}'); + print('❌ ERROR[${error.response?.statusCode}] => MESSAGE: ${error.message}'); } return handler.next(error); }, ), ); - - // Add logging interceptor in debug mode + // === DIO LOGGING INTERCEPTOR (debug only) === if (kDebugMode) { - _dio.interceptors.add(LogInterceptor( - request: true, - requestHeader: true, - requestBody: true, - responseHeader: false, - responseBody: true, - error: true, - )); + _dio.interceptors.add( + LogInterceptor( + request: true, + requestHeader: true, + requestBody: true, + responseHeader: false, + responseBody: true, + error: true, + ), + ); } } - // GET API Request Future getApi({ required String url, @@ -83,7 +112,6 @@ class NetworkApiService { throw _handleError(e); } } - // POST API Request Future postApi({ required String url, @@ -107,51 +135,6 @@ class NetworkApiService { throw _handleError(e); } } - - // PUT API Request (Bonus) - Future putApi({ - required String url, - dynamic data, - Map? queryParameters, - Options? options, - CancelToken? cancelToken, - }) async { - try { - final response = await _dio.put( - url, - data: data, - queryParameters: queryParameters, - options: options, - cancelToken: cancelToken, - ); - return response; - } on DioException catch (e) { - throw _handleError(e); - } - } - - // DELETE API Request (Bonus) - Future deleteApi({ - required String url, - dynamic data, - Map? queryParameters, - Options? options, - CancelToken? cancelToken, - }) async { - try { - final response = await _dio.delete( - url, - data: data, - queryParameters: queryParameters, - options: options, - cancelToken: cancelToken, - ); - return response; - } on DioException catch (e) { - throw _handleError(e); - } - } - // Error Handler String _handleError(DioException error) { String errorDescription = ""; @@ -184,9 +167,8 @@ class NetworkApiService { } return errorDescription; } - - // Update headers (e.g., add token) + // Update headers (e.g., add auth token) void updateHeaders(Map headers) { _dio.options.headers.addAll(headers); } -} +} \ No newline at end of file