エラーをスローする
CoddyのFlutterジャーニー「データとネットワーク」セクションの一部。レッスン 11/27。
エラーが発生するのはサーバーだけではありません。自分で作った関数も処理を続けられないことがあります。関数が扱えないものを受け取ると、例外をスローします。
Future<void> saveName(String name) async {
if (name.isEmpty) {
throw Exception('The name cannot be empty');
}
// 名前を保存する
}throwはreturnのように、その場で関数を停止しますが、値ではなくエラーを返します。Exception('...')はエラーで、何が問題だったのかを示すメッセージが含まれています。
その関数を呼び出した側は、fetchからのエラーとまったく同じように、tryとcatchでエラーを捕捉します。テキストに変換すると、ExceptionはException: で始まり、その後にメッセージが続きます。
実際のfetchも同じように動作します。サーバーからのすべての応答にはステータスコードが付いています。200はOK、404は見つからないことを意味します。200以外の場合、コードは例外をスローするため、画面に壊れた応答がデータであるかのように表示されることはありません。
final response = await http.get(Uri.parse(url));
if (response.statusCode != 200) {
throw Exception('The server answered ${response.statusCode}');
}
return response.body;チャレンジ
簡単フィールドが空の状態でSaveをタップすると、名前がないのにSaved: と表示されます。saveNameが空の名前を拒否するようにしてください。待機後、nameが空の場合はException('The name cannot be empty')をスローします。save関数はすでに例外をキャッチしてメッセージを表示します。
自分で試してみよう
import 'package:flutter/material.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: NameScreen(),
);
}
}
class NameScreen extends StatefulWidget {
const NameScreen({super.key});
@override
State<NameScreen> createState() => _NameScreenState();
}
class _NameScreenState extends State<NameScreen> {
final controller = TextEditingController();
String status = '';
@override
void dispose() {
controller.dispose();
super.dispose();
}
Future<void> saveName(String name) async {
await Future.delayed(const Duration(seconds: 1));
}
Future<void> save() async {
try {
await saveName(controller.text);
setState(() {
status = 'Saved: ${controller.text}';
});
} catch (e) {
setState(() {
status = '$e';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: controller,
decoration: const InputDecoration(labelText: 'Name'),
),
const SizedBox(height: 16),
ElevatedButton(onPressed: save, child: const Text('Save')),
const SizedBox(height: 16),
Text(status, style: const TextStyle(fontSize: 18)),
],
),
),
);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
データとネットワークのすべてのレッスン
自分で練習してみよう: Flutterオンラインコンパイラ