Flutter: グローバルなエラーハンドリング

Flutter: グローバルなエラーハンドリング

December 8, 2022

Flutter にて、個別に try/catch されなかったエラーをアプリのルートでまとめてハンドリングする方法です。

TL;DR #

これで未ハンドリングエラーを捕捉することができます。

void main() {
  FlutterError.onError = (details) {
    // ハンドリング処理
  };

  PlatformDispatcher.instance.onError = (error, stack) {
    // ハンドリング処理
    return true;
  };

  runApp(const MyApp());
}

説明 #

リファレンス #

サンプルコード #

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.onErrorPlatformDispatcher.instance.onError が機能しません。

そのため、開発中に確認したいときはデバッグ無しのモードで実行する必要があります。次の画像は VSCode で実行する場合の例です。

VSCode