Flash10.0は例外をちゃんと処理できないね…

Flash以外のプログラマにとっては驚愕かもしれませんが、Flash Player 10.0には、グローバルなランタイム例外を捕まえるためのしくみがありません。たとえばイベントリスナの処理中にNull Pointer Exceptionが発生したとしても、イベントリスナ内で例外をcatchするコードを書かなければ、ユーザレベルでcatchする方法はありません。javaなどのようにmain関数があるわけではないので、システム大域に効くようなtry-catchが書けないのです。

例外が発生してプログラムが止まってくれるならまだよかったのですが、Flash Playerは、なんと、例外がcatchされなかった場合、一切警告なく*1、動作を継続*2します。

つまり、プログラムがバグっていても、バグっていることが誰にも分からないままプログラムの実行が続いてしまうわけです。フレームワークの設計としてありえないレベルの問題なので、AdobeのフォーラムでもこのFlash Player仕様をなんとかしてほしいという記事に投票が集まっていました。

https://bugs.adobe.com/jira/browse/FP-444

Flash Playerがこのような仕様になっていることに言及している日本語リソースは不思議と見当たりません。国内ではFlashをメインに据えて(クリティカルな)UIを作るというケースがまだ少ないためだと思います。

世の中に出回っているFlashファイルの多くは、例外で落ちまくっています。画面遷移中にボタンを連打すると画面が真っ白になるFlashファイルや、移動中のオブジェクトを連打するとオブジェクトが吹き飛ぶようなFlashファイルを見たことはありませんか?そのようなFlashファイルは内部的に例外を出してクラッシュしている可能性があります。しかし、それが問題視されることは滅多にありません。ゲームや広告のFlashの場合は、画面が多少崩れてもビジネスに深刻なダメージを与えることは少なく、画面が多少崩れてもなんとなく動作を続けるほうが、ユーザ体験が良い場合すらあります。このため、Flash Playerが例外を握りつぶしたとしても、それは欠陥ではなく、ありがたいリカバリのしくみとして機能しているケースの方が多いのではないかと推測します。

しかしこれが物販・金融などのサイトのUIとなれば話は別です。これは極端な例ですが、FXサイトの為替レート表示UIをFlashで作ったとしましょう。そしてそのUIのバグでNullPointerExceptionが出てしまい、それ以降為替レートの更新が止まったとします。しかしユーザーはFlash Playerがエラーを出さないのでその事実に気が付きません。最悪の場合、ユーザーはそのまま古い為替レートを現在の値と勘違いしたまま…ということがあるかもしれません。もちろん、例外でプログラムが止まったらそれはそれでクレームになるでしょう。しかし、ユーザーを誤解させるよりは、プログラムを止めてしまった方がマシなケースはいくらでも想像がつきます。

さて、このグローバルな例外の発生を検知できないという問題は、かなり致命的で、最初の指摘が2007年ごろに行われているにもかかわらず、なぜか今まで修正される気配がありませんでした。技術的に、VMで例外を処理するためのグローバルフックをサポートできないような問題があったとは思えないのですが、なぜだったのでしょうね。もしかするとセキュリティ的な理由が絡むのかもしれません。

とりあえず現在はFlash Player 10.1の機能として追加が決定しているようです。

http://labs.adobe.com/technologies/flashplayer10/features.html#developer

この問題が修正されたFlash Playerが普及してくれると、ようやくFlashで信頼性の高いシステムが作れるかも…という気になってきます。早いリリース&普及を心待ちにしています。

*1:デバッグFlash Playerの場合はエラーダイアログが出ます

*2:例外が発生した場所からプログラムの処理が継続されるわけではないです。例外発生時点での関数呼び出しスタックは破棄されますが、その後のイベントループがそのまま行われるため、実質的にはプログラムの動作が続いているように見えます。