Menu
CoddyTech

tryでエラーを捕捉する

CoddyのFlutterジャーニー「データとネットワーク」セクションの一部。レッスン 10/27。

ネットワーク呼び出しは失敗することがあります。スマートフォンの電波が届かない、サーバーが停止している、パスが間違っているなどです。fetchが失敗すると、エラー(ApiException)をスローします。これはapi.dartの先頭にある小さなクラスで、statusCodeとmessageを持っています。捕捉されないエラーが発生すると関数は停止し、Consoleに赤いエラーが表示され、画面にはいつまでも終わらないスピナーが表示されます。

tryとcatchで捕捉しましょう。

try {
  final text = await fetch('/message');
  // fetchが成功したときだけ実行される
} catch (e) {
  // fetchが例外をスローしたときだけ実行される
  print('It failed: $e');
}

Dartはtryブロックを実行します。その中で何かがスローされると、Dartはすぐにcatchへ移り、eにエラーが格納されます。try内で失敗した行より後の行は実行されません。

スローされるのはawaitの行なので、await自体をtryの中に置きます。その後、クラッシュさせるのではなく、何が起きたのかを言葉で画面に表示しましょう。

プレビューで失敗を確認するには、mainの最初の行にoffline = true;と書いて、Runを押します。offlineはapi.dartにあり、スマートフォンの電波が届かないときのように、すべての呼び出しを失敗させます。Checkを押す前に、この行を削除してください。

challenge icon

チャレンジ

中級

呼び出しが失敗してもloadMessageが動作するようにします:

  • fetchと、その後のsetStateをtryブロックに入れます
  • catch (e)では、スピナーを停止し、メッセージをCould not load: $eに設定します

自分で試してみよう

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')),
          ],
        ),
      ),
    );
  }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

データとネットワークのすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ