この記事はFlutter #1 Advent Calendar 2020の9日目の記事...の予定で書いてたのですが、公開が間に合わず他の方が9日目の記事を書いてくださっていたので、Advent Calendarは関係なくなりました😇
私が開発に関わっているAndroidアプリでは、開発版アプリでクラッシュが起きた際に、エラー内容や端末情報を特定のSlackチャンネルに投稿する仕組みをよく作ります。
Androidアプリであれば、Thread.setDefaultUncaughtExceptionHandler
等を使ってアプリがクラッシュした際それをハンドリングして、任意の処理を行う実装ができます。
その辺の詳細については、「Androidアプリ開発で例外の発生した場所を特定する」の記事などを読むといいかと思います。
今回は、これと似たものをFlutterアプリで実装する方法を紹介します。
サンプルコードをGitHubで公開していますので、合わせてどうぞ。
https://github.com/operando/send_fultter_error_to_slack
そもそもなぜクラッシュをハンドリングして、エラー内容をSlackに投稿するのか
開発版アプリは社内の色んなメンバーが日々触るので、誰かの手元で起きたクラッシュのエラー内容を見逃さない仕組みが必要だと思ってます。
Slackに投稿すれば、私はそれなりに気づくことができるので、そんな感じの仕組みをアプリに実装して運用しています。
Flutterのエラーハンドリングを理解する
以下 2つの公式ドキュメントが参考になりました。
クラッシュが起きた時に、それをハンドリングして任意の処理を実行することができそうなのがわかりました。
エラーハンドリングして、エラー内容をSlackに投稿する
以下のようにmain関数でエラーハンドリングの実装し、クラッシュが起きた時にそれをハンドリングしてエラー内容をSlackに投稿します。
void main() {
runZonedGuarded<Future<void>>(() async {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (FlutterErrorDetails details) async {
FlutterError.dumpErrorToConsole(details);
if (kDebugMode) {
await sendError(details.exceptionAsString());
}
exit(1);
};
runApp(MyApp());
}, (dynamic error, StackTrace stackTrace) async {
if (kDebugMode) {
await sendError(error.toString());
}
exit(1);
});
}
Future<void> sendError(String text) async {
final response = await http.post('https://slack.com/api/chat.postMessage?channel=XXXXX&text=$text',
headers: { "Authorization": "Bearer XXXXXX" });
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');
}
kDebugMode
を使って、アプリがデバッグモードで動作してる時だけエラー内容をSlackに投稿するようにしてます。
今回の実装では送っているエラー内容は簡素なものですが、実装次第では端末情報などもっと詳細な内容を含めることもできると思います。
ちなみに、エラーハンドリングの実装自体がわかれば、Slack以外のサービスにに投稿したりなど、色んなことができると思います。
例えば、GitHubにエラー内容のissueを作るとかもできると思います。
実際に動かしてみる
アプリにエラーハンドリングを実装し、ボタンを押すとクラッシュが起きるようにして実際に動かしてみます。
以下のようにアプリがクラッシュすると、エラー内容がSlackに投稿されます。
おまけ : Catcher
今回紹介したようなエラーハンドリングをして、エラー内容をなんか色々するCatcherというライブラリを見つけました。
このライブラリを使うと自前でエラーハンドリングする実装が省けます。
また、ハンドリングしたエラー内容を様々な方法でレポーティングする仕組みがライブラリで用意されています。
例えば、Slack Handlerがあったりするので、これを使えばSlackに投稿する実装はライブラリに任せることができるので、実装がとても楽になります。