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を押す前に、この行を削除してください。
チャレンジ
中級呼び出しが失敗しても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')),
],
),
),
);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
データとネットワークのすべてのレッスン
自分で練習してみよう: Flutterオンラインコンパイラ