import 'package:flutter/material.dart';
class NetworkErrorHandlingScreen extends StatefulWidget {
@override
State<NetworkErrorHandlingScreen> createState() => _NetworkErrorHandlingScreenState();
}
class _NetworkErrorHandlingScreenState extends State<NetworkErrorHandlingScreen> {
String? data;
String? errorMessage;
bool isLoading = false;
Future<void> fetchData() async {
setState(() {
isLoading = true;
errorMessage = null;
data = null;
});
try {
// Simulate network delay
await Future.delayed(Duration(seconds: 2));
// Simulate success or failure randomly
final success = DateTime.now().second % 2 == 0;
if (success) {
data = 'Fetched data from network at ${DateTime.now()}';
} else {
throw Exception('Network error occurred');
}
} catch (e) {
errorMessage = e.toString();
} finally {
setState(() {
isLoading = false;
});
}
}
@override
void initState() {
super.initState();
fetchData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Network Error Handling')),
body: Center(
child: isLoading
? CircularProgressIndicator()
: errorMessage != null
? Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Error: $errorMessage', style: TextStyle(color: Colors.red), textAlign: TextAlign.center),
SizedBox(height: 16),
ElevatedButton(
onPressed: fetchData,
child: Text('Retry'),
),
],
)
: Text(data ?? 'No data', textAlign: TextAlign.center),
),
);
}
}
This solution uses a StatefulWidget to manage the network call state.
Inside fetchData(), we use a try-catch block to simulate a network call that may succeed or fail.
While loading, a spinner is shown. If an error happens, an error message and a Retry button appear. On success, the fetched data text is displayed.
The Retry button calls fetchData() again to try fetching data.
This approach keeps the UI responsive and user-friendly by clearly showing loading, success, and error states.