Menu
CoddyTech

O estado de erro do FutureBuilder

Parte da seção Dados e rede do Journey de Flutter da Coddy. Lição 13 de 27.

Um FutureBuilder captura erros para você. Quando o future dele lança uma exceção, nada trava: o builder é executado novamente com snapshot.hasError definido como true, e snapshot.error contém o que foi lançado.

Isso dá a cada tela de carregamento três estados, e o builder trata cada um deles:

if (snapshot.hasError) {
  return Text('Could not load: ${snapshot.error}');
}
if (snapshot.hasData) {
  return Text(snapshot.data!);
}
return const CircularProgressIndicator();

Erro, dados e, caso contrário, ainda carregando. Um builder que só sabe lidar com dados mostra o indicador de carregamento para sempre quando a chamada falha, porque nunca há dados.

Coloque cada verificação antes do return que a ocultaria. Se o return do indicador de carregamento vier primeiro para "sem dados", a linha de erro abaixo dele nunca poderá ser executada.

Para vê-lo falhar na prévia, escreva offline = true; como a primeira linha de main e pressione Run. offline vem de api.dart: ele faz todas as chamadas falharem como se o celular estivesse sem sinal. Remova a linha antes de pressionar Check.

challenge icon

Desafio

Médio

Sem conexão, esta tela fica carregando para sempre. Dê ao builder seu estado de erro: quando snapshot.hasError, exiba Could not load: seguido de snapshot.error, com tamanho 20.

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> {
  late Future<String> _message;

  @override
  void initState() {
    super.initState();
    _message = fetch('/message');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<String>(
          future: _message,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data!, style: const TextStyle(fontSize: 24));
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de Flutter online