Una llamada de red con tiempo límite y reintentos
Una función genérica que envuelve cualquier Future: corta si tarda demasiado y reintenta un número fijo de veces.
El problema
En una app móvil la red se cae y vuelve. Una llamada sin tiempo límite deja la pantalla girando para siempre; una sin reintento convierte un túnel en un error.
import 'dart:async';
Future<T> conReintento<T>(Future<T> Function() tarea, {int intentos = 3, Duration limite = const Duration(seconds: 5)}) async {
for (var i = 1; ; i++) {
try {
return await tarea().timeout(limite);
} on TimeoutException {
if (i >= intentos) rethrow;
print('Intento $i: sin respuesta en ${limite.inSeconds}s, reintento');
} catch (e) {
if (i >= intentos) rethrow;
print('Intento $i falló: $e');
}
await Future.delayed(Duration(milliseconds: 300 * i));
}
}
Future<void> main() async {
var llamadas = 0;
final dato = await conReintento(() async {
llamadas++;
if (llamadas < 3) throw Exception('red caída');
return 'perfil cargado';
});
print('$dato tras $llamadas intentos');
}
Por qué está escrito así
- timeout convierte una espera eterna en una TimeoutException a los cinco segundos.
- rethrow relanza el error original conservando su traza: quien llama ve la causa real.
- La pausa crece con cada intento (300, 600, 900 ms) para no insistir sobre una red que recién vuelve.
- Al ser genérica, sirve igual para un perfil, una lista o un archivo.
Guardalo como reintento.dart y corré: dart run reintento.dart. También corre en dartpad.dev.
timeout deja de esperar, pero no cancela la llamada: el pedido sigue vivo por debajo. Para cancelar de verdad hace falta que el cliente HTTP lo soporte.
Adaptalo a tu caso con IA
El botón copia este prompt con el código pegado debajo. Reemplazá los corchetes con lo tuyo y pegalo en ChatGPT, Claude, Gemini o Copilot.
Tengo esta función de reintento con tiempo límite en Dart. Adaptala para usarla en Flutter con [PAQUETE HTTP: http, dio], que solo reintente errores de red y códigos 5xx (nunca 4xx), que cancele de verdad el pedido al vencer el tiempo y que exponga el estado para mostrar "reintentando…" en pantalla con [GESTOR DE ESTADO]. Mostrame el uso en un botón de recargar.
Ejemplo escrito y revisado a mano.
Comentarios
Todavía no hay comentarios. El primero puede ser el tuyo.
¿Lo adaptaste a algo tuyo?
Contame qué resolviste con esto, o qué le faltó.