Flash Player 10.1 から、グローバルエラーハンドラーの機能が追加されました。これにより、未処理のエラーを一括して扱うことが可能になります。
従来は、明示的に処理ロジックの記述されていない Error または ErrorEvent が実行時に発生した場合、その情報を知ることはできませんでした。(デバッグプレーヤーでは、ダイアログボックスが開いてエラーメッセージが表示される) ですが、起こり得る全てのエラーに対して、処理を記述するというのはなかなか面倒かつ困難です。
そこで、Flash Player 10.1 からは、未処理のエラーをまとめて処理できるよう、新しい機能が追加されたというわけです。
実行時エラー処理について
グローバルエラー処理の話の前に、普通のエラー処理についておさらいです。
まず、ここでエラーと言っているのは、実行時に起こるエラーのことです。(例えば、ある URL から swf ファイルを読み込もうとしたら失敗したとか) コンパイル時のエラーではありません。(文法が違ったとか)
ActionScript 3 では、実行時エラーを 2 種類に分けて扱います。
- Error クラス (と、そのサブクラス):
エラーの発生が、実行中のスクリプトから直接扱える場合。関数呼び出しにより起きる実行時エラーはこのタイプ。IOError, TypeError など。 - ErrorEvent クラス (と、そのサブクラス):
エラーの発生が実行中のスクリプトと非同期になる場合。イベントハンドラーで結果を受け取る処理はこのタイプ。IOErrorEvent, SecurityErrorEvent など。StatusEvent などもこれに含める。
上の 2 種類は、それぞれエラー発生の通知のタイミングが、同期/非同期と異なるため、エラー処理の記述も異なります。同期型のエラーの場合は、try..catch..finally を使ってエラー処理を記述します。一方、非同期エラーの場合は、非同期処理を実行するオブジェクトにエラーイベント用のハンドラーを追加します。
(繰り返しになりますが、新しく追加されたグローバルエラーハンドラーは、上記のようなエラー処理の記述されていないエラーを扱うための手段です。同期/非同期どちらのタイプのエラーも扱えます)
try..catch..finally の使い方
さて、ここで、同期エラー処理の基本となる try..catch..finally の使い方について、すこし具体的にします。
try..catch..finally は、エラー発生時の処理を記述するための構文です。エラーが起きると、スクリプトの実行が中断されるため、エラーの起きる可能性のある範囲を try ブロックで囲みます。そして、エラーの起きたときの処理を catch ブロックの中に記述します。catch 文の横には、処理の対象となるエラーオブジェクトの型を宣言します。
try { // ここに、エラー発生の可能性があるスクリプトを記述 // エラーが発生すると、エラーの発生した行以降のスクリプトは実行されない } catch (error:Error) { // エラーにより Error オブジェクトが生成されると、ここにジャンプする // エラー処理用のコードを記述する } finally { // エラーが起きても起きなくても実行される // 確実に実行しておきたい処理がある場合に使用する }
エラーが起きなかった場合は、try → finally の順に、エラーが起きた場合は、try → catch → finally の順に実行されます。(finally ブロックは常に実行される)
try..catch..finally 文の追加自体はあまりパフォーマンスに影響しないので、必要であればとりあえず書く、という考え方でよいと思います。実際にエラーが発生したときの処理自体はどちらかというと重いものになりますが、実行時エラーはめったに起こらない & 重要度が高いはずですし、こちらもあまり気にしなくてよいでしょう。
複数の種類のエラーが発生するケースでは、catch 文を複数並べて、エラーの種類に応じた個別の処理を記述できます。その際、それぞれの catch 文に、処理したいエラーのクラス (Error, IOError 等) を指定します。
catch ブロックが複数ある場合、上から順番に、発生したエラーオブジェクトの型と catch 文に指定されたクラスが比較されます。最初に型が一致した catch 文のみが実行されるため、子クラスは常に親クラスより上に指定するようにします。
下の例は、Sound オブジェクトにデータを読み込む際の IOError とその他の Error を、個別に処理する場合のサンプルです。
try { sound.close() } catch (error:IOError) { // MP3 ファイル読み込みに失敗した場合の処理 } catch (error:Error) { // その他のエラーの処理 }
ちゃんと IOError の catch 文が Error の catch 文の先に宣言されているのが大事な点です。この順が逆になると、IOError が発生してもその他のエラーの処理が呼び出されてしまいます。
try..catch を入れ子にすることもできます。
try { try { sound.close() } catch (error:IOError) { // MP3 ファイル読み込みに失敗した場合の処理 } catch (error:Error) { // その他のエラーの処理 }
とりあえず、今回はここまでです。
コメントする