Przechwytywanie błędów za pomocą try
Część sekcji Dane i sieć ścieżki Flutter w Coddy. Lekcja 10 z 27.
Połączenie sieciowe może się nie powieść: telefon nie ma zasięgu, serwer nie działa albo ścieżka jest nieprawidłowa. Gdy fetch się nie powiedzie, zgłasza błąd: ApiException, czyli małą klasę na początku pliku api.dart, zawierającą statusCode i message. Błąd, którego nikt nie przechwytuje, przerywa działanie funkcji i pojawia się w konsoli jako czerwony komunikat o błędzie, a użytkownik widzi kręcące się kółko, które nigdy nie znika.
Przechwyć go za pomocą try i catch:
try {
final text = await fetch('/message');
// wykonuje się tylko wtedy, gdy fetch się powiodło
} catch (e) {
// wykonuje się tylko wtedy, gdy fetch zgłosiło wyjątek
print('It failed: $e');
}Dart wykonuje blok try. Jeśli cokolwiek w nim zgłosi błąd, Dart natychmiast przechodzi do catch, a e zawiera błąd. Wiersze po tym, który spowodował błąd w bloku try, nigdy nie zostaną wykonane.
Umieść samo await wewnątrz try: to właśnie ten wiersz zgłasza błąd. Następnie wyjaśnij użytkownikowi, co się stało, zamiast doprowadzać do awarii.
Aby zobaczyć błąd w podglądzie, wpisz offline = true; jako pierwszy wiersz funkcji main i naciśnij Run. offline pochodzi z api.dart: sprawia, że każde połączenie kończy się niepowodzeniem, tak jakby telefon nie miał zasięgu. Usuń ten wiersz, zanim naciśniesz Check.
Wyzwanie
ŚredniSpraw, aby loadMessage działało mimo nieudanego wywołania:
- umieść
fetchi następujące po nimsetStatew blokutry - w
catch (e)zatrzymaj wskaźnik ładowania i ustaw wiadomość naCould not load: $e
Spróbuj swoich sił
import 'package:flutter/material.dart';
import 'api.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: MessageScreen(),
);
}
}
class MessageScreen extends StatefulWidget {
const MessageScreen({super.key});
@override
State<MessageScreen> createState() => _MessageScreenState();
}
class _MessageScreenState extends State<MessageScreen> {
String message = 'No message yet';
bool loading = false;
Future<void> loadMessage() async {
setState(() {
loading = true;
});
final text = await fetch('/message');
setState(() {
message = text;
loading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
loading
? const CircularProgressIndicator()
: Text(message, style: const TextStyle(fontSize: 24)),
const SizedBox(height: 24),
ElevatedButton(onPressed: loadMessage, child: const Text('Load message')),
],
),
),
);
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Dane i sieć
3Gdy wywołania kończą się niepowodzeniem
Przechwytywanie błędów za pomocą tryZgłaszanie błęduSprzątanie za pomocą finallyStan błędu w FutureBuilderPrzycisk „Spróbuj ponownie”Poćwicz samodzielnie: Kompilator Flutter online