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 で実行する場合の例です。
