一般社団法人 全国個人事業主支援協会

COLUMN コラム

〜ArgumentErrorをmain.dartでキャッチする方法〜

アプリ開発をしていると、「気づかないところでエラーが起きていた…」 という経験は誰しもあると思います。
特にFlutterでは、UI層のエラー・非同期処理のエラー・Dartレベルのエラーがそれぞれ異なる経路で流れるため、
「全部まとめてキャッチしたい!」と思った時に少し迷います。

そこで今回は、main.dartでエラーを一元的にリッスンする方法を整理してみます。


1. FlutterError.onError ― ウィジェット内のエラーを拾う

Flutterには最初から「UIフレームワーク内で発生したエラー」を捕まえるフックが用意されています。

void main() {
FlutterError.onError = (FlutterErrorDetails details) {
// デフォルトの挙動を残す場合
FlutterError.dumpErrorToConsole(details);
// ここでCrashlytics送信なども可能
};

runApp(MyApp());
}

これで、ArgumentErrorなどがウィジェットツリー内で発生したときに検知できます。
ただし、非同期処理のエラーまではカバーできません。


2. runZonedGuarded ― 非同期エラーも含めて守る

FutureやTimerなど、非同期処理で投げられた例外は FlutterError.onError では拾えません。
そこで便利なのが runZonedGuarded

void main() {
runZonedGuarded(
() => runApp(MyApp()),
(error, stack) {
print(‘Caught: $error’);
},
);
}

これを使うと、非同期処理で飛んできたエラーもキャッチできます。
バックエンド通信やタイマー処理が絡むアプリでは必須レベルです。


3. PlatformDispatcher.instance.onError ― Dart VMレベルで最後の砦

Flutter 3.3以降では、Dart VM自体が提供するエラーフックも用意されています。

void main() {
PlatformDispatcher.instance.onError = (error, stack) {
print(‘Global error: $error’);
return true; // 処理済みにする
};

runApp(MyApp());
}

これは、**「ここまで捕まらなければ本当にアプリが落ちる」**という最終防衛ライン。
CrashlyticsやSentryにエラーを送っておけば、調査時に役立ちます。


まとめ ― 3段構えでエラーを逃さない

Flutterアプリのエラー監視は以下の三段構えで考えると安心です。

  1. FlutterError.onError → UI層の例外

  2. runZonedGuarded → 非同期処理の例外

  3. PlatformDispatcher.onError → Dartレベルの例外

これらを組み合わせれば、ArgumentErrorを含め、アプリ内の「想定外エラー」を逃さずログに残せます。


最後に

アプリはユーザーの手元で予期せぬ環境に晒されます。
「落ちない」アプリを作ることは理想ですが、現実は落ちます。
だからこそ、落ちた時に「なぜ落ちたのか」を知る仕組みをmain.dartで仕込んでおくことが、実は開発者の一番の武器になります。

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア