Ошибка Future и повтор в Flutter
Сеть и файлы иногда падают. У
AsyncSnapshot есть hasError
и error - их проверяют в
FutureBuilder
после ожидания, но до hasData.
Чтобы повторить запрос, создайте новый
Future и обновите состояние:
храните счётчик или ссылку на Future в
State и в setState подставляйте
свежий вызов. Кнопка «Повторить» только
запускает этот цикл заново:
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: ErrorRetryPage()));
}
class ErrorRetryPage extends StatefulWidget {
const ErrorRetryPage({super.key});
@override
State<ErrorRetryPage> createState() => _ErrorRetryPageState();
}
class _ErrorRetryPageState extends State<ErrorRetryPage> {
late Future<String> task;
int attempt = 0;
@override
void initState() {
super.initState();
task = load();
}
Future<String> load() {
attempt++;
final current = attempt;
return Future<String>.delayed(
const Duration(milliseconds: 800),
() {
if (current < 2) { // first attempts fail on purpose
throw Exception('Server unavailable');
}
return 'Success on try $current';
},
);
}
void retry() {
setState(() {
task = load();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Error')),
body: Center(
child: FutureBuilder<String>(
future: task,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('${snapshot.error}'),
const SizedBox(height: 12),
ElevatedButton(
onPressed: retry,
child: const Text('Retry'),
),
],
);
}
if (snapshot.hasData) {
return Text(snapshot.data!);
}
return const SizedBox.shrink();
},
),
),
);
}
}
Сделайте загрузку, которая всегда падает
с текстом 'No connection'. Покажите
его на экране и кнопку «Try again», после
которой снова виден индикатор.