import 'dart:async'; import 'dart:io'; import 'package:http/http.dart' as http; import 'net_guard.dart'; typedef BodyEncoder = Future Function(); class HttpRetry { /// ريتراي لـ network/transient errors فقط. static Future sendWithRetry( BodyEncoder send, { int maxRetries = 3, Duration baseDelay = const Duration(milliseconds: 400), Duration timeout = const Duration(seconds: 12), }) async { // ✅ Pre-flight check for internet connection if (!await NetGuard().hasInternet()) { // Immediately throw a specific exception if there's no internet. // This avoids pointless retries. throw const SocketException("No internet connection"); } int attempt = 0; while (true) { attempt++; try { final res = await send().timeout(timeout); return res; } on TimeoutException catch (_) { if (attempt >= maxRetries) rethrow; } on SocketException catch (_) { if (attempt >= maxRetries) rethrow; } on HandshakeException catch (_) { if (attempt >= maxRetries) rethrow; } on http.ClientException catch (e) { // مثال: Connection reset by peer final msg = e.message.toLowerCase(); final transient = msg.contains('connection reset') || msg.contains('broken pipe') || msg.contains('timed out'); if (!transient || attempt >= maxRetries) rethrow; } // backoff: 0.4s, 0.8s, 1.6s final delay = baseDelay * (1 << (attempt - 1)); await Future.delayed(delay); } } }