Capturando erros com try
Parte da seção Dados e rede do Journey de Flutter da Coddy. Lição 10 de 27.
Uma chamada de rede pode falhar: o celular está sem sinal, o servidor está fora do ar, o caminho está errado. Quando fetch falha, ela lança um erro: uma ApiException, uma pequena classe no início de api.dart com um statusCode e uma message. Um erro que ninguém captura interrompe sua função e aparece como um erro em vermelho no Console, e a pessoa vê um indicador de carregamento que nunca termina.
Capture-o com try e catch:
try {
final text = await fetch('/message');
// só é executado quando fetch funciona
} catch (e) {
// só é executado quando fetch lança uma exceção
print('It failed: $e');
}Dart executa o bloco try. Se algo nele lançar um erro, Dart vai direto para catch, e e guarda o erro. As linhas após a que falhou em try nunca são executadas.
Coloque o próprio await dentro de try: é essa linha que lança o erro. Em seguida, explique à pessoa o que aconteceu, em palavras, em vez de deixar o programa travar.
Para ver a falha na prévia, escreva offline = true; como a primeira linha de main e pressione Executar. offline vem de api.dart: ele faz todas as chamadas falharem como se o celular estivesse sem sinal. Remova a linha antes de pressionar Verificar.
Desafio
MédioFaça com que loadMessage continue funcionando mesmo quando uma chamada falhar:
- coloque o
fetche osetStateque vem depois dele em um blocotry - em
catch (e), pare o indicador de carregamento e defina a mensagem comoCould not load: $e
Experimente você mesmo
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')),
],
),
),
);
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Dados e rede
3Quando as chamadas falham
Capturando erros com tryLançando um erroFazendo a limpeza com finallyO estado de erro do FutureBuilderUm botão para tentar novamentePratique por conta própria: Compilador de Flutter online