Flutter: グローバルなエラーハンドリング
December 8, 2022
Flutter にて、個別に try/catch
されなかったエラーをアプリのルートでまとめてハンドリングする方法です。
TL;DR #
これで未ハンドリングエラーを捕捉することができます。
void main() {
FlutterError.onError = (details) {
// ハンドリング処理
};
PlatformDispatcher.instance.onError = (error, stack) {
// ハンドリング処理
return true;
};
runApp(const MyApp());
}
説明 #
リファレンス #
- Handling errors in Flutter | Flutter
- https://docs.flutter.dev/testing/errors
サンプルコード #
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
FlutterError.onError = (details) {
print('--- FlutterError.onError ---');
};
PlatformDispatcher.instance.onError = (error, stack) {
print('--- PlatformDispatcher.instance.onError ---');
return true;
};
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyAppPage(),
);
}
}
class MyAppPage extends StatelessWidget {
const MyAppPage({super.key});
@override
Widget build(BuildContext context) {
// #1
throw Exception('Will caught by FlutterError.onError');
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
child: const Text('throw Exception()'),
onPressed: () {
// #2
throw Exception(
'Will caught by FlutterError.onError',
);
},
),
ElevatedButton(
child: const Text('throw async Exception()'),
onPressed: () async {
// #3
throw Exception(
'Will caught by PlatformDispatcher.instance.onError',
);
},
),
],
),
);
}
}
上記のコードには3ヶ所の例外発生ポイントがありますが、それぞれハンドリング場所が異なります。
- 同期処理は Flutter によって捕捉され
FlutterError.onError
が実行されます。 - 非同期処理は Flutter によっては捕捉されず
PlatformDispatcher.instance.onError
が実行されます。
捕捉 #
デバッグモードで実行すると FlutterError.onError
や PlatformDispatcher.instance.onError
が機能しません。
そのため、開発中に確認したいときはデバッグ無しのモードで実行する必要があります。次の画像は VSCode で実行する場合の例です。