Gestire gli errori con try
Fa parte della sezione Dati e rete del percorso Flutter di Coddy. Lezione 10 di 27.
Una chiamata di rete può non riuscire: il telefono non ha segnale, il server è inattivo, il percorso è errato. Quando fetch non riesce, genera un errore: un’ApiException, una piccola classe all’inizio di api.dart con un statusCode e un message. Un errore che nessuno intercetta interrompe la tua funzione e compare come errore rosso nella Console, mentre la persona vede un indicatore di caricamento che non si ferma mai.
Intercettalo con try e catch:
try {
final text = await fetch('/message');
// viene eseguito solo quando fetch è riuscito
} catch (e) {
// viene eseguito solo quando fetch ha generato un'eccezione
print('It failed: $e');
}Dart esegue il blocco try. Se qualcosa al suo interno genera un errore, Dart passa direttamente a catch e e contiene l’errore. Le righe successive a quella che ha causato l’errore nel blocco try non vengono mai eseguite.
Inserisci lo stesso await dentro try: è quella la riga che genera l’errore. Poi spiega alla persona cosa è successo, a parole, invece di mandare in crash l’app.
Per vedere l’errore nell’anteprima, scrivi offline = true; come prima riga di main e premi Run. offline proviene da api.dart: fa sì che ogni chiamata non riesca, come se il telefono non avesse segnale. Rimuovi la riga prima di premere Check.
Sfida
MedioFai in modo che loadMessage gestisca una chiamata non riuscita:
- inserisci
fetche ilsetStatesuccessivo in un bloccotry - in
catch (e), arresta lo spinner e imposta il messaggio suCould not load: $e
Provalo tu
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')),
],
),
),
);
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Dati e rete
3Quando le chiamate falliscono
Gestire gli errori con tryLanciare un errorePulire con finallyLo stato di errore di FutureBuilderUn pulsante per riprovareEsercitati da solo: Compilatore Flutter online