アプリケーションの同期エラーの処理

Flash Player 9 以降、Adobe AIR 1.0 以降

最も一般的なエラー処理は同期エラー処理のロジックで、アプリケーションの実行時に同期エラーをキャッチするためのステートメントをコードに挿入します。この種類のエラー処理では、関数失敗時のランタイムエラーをアプリケーションで認識してそこから回復できます。 同期エラーをキャッチするロジックに try..catch..finally ステートメントがあります。このステートメントは実際に操作を試し、Flash ランタイムからのエラー応答をキャッチし、失敗した操作を処理するために最後に何らかの操作を実行します。

try..catch..finally ステートメントの使用

同期的なランタイムエラーを扱う場合は、 try..catch..finally ステートメントを使用してエラーをキャッチします。ランタイムエラーが発生すると、Flash ランタイムは例外をスローします。これは、通常の実行処理を中断し、Error 型の特殊なオブジェクトを作成することを意味します。この Error オブジェクトは、該当する最初の catch ブロックにスローされます。

try ステートメントは、エラーが発生する可能性のあるステートメントを囲みます。 try ステートメントには必ず catch ステートメントが伴います。 try ステートメントのブロック内にある何らかのステートメントでエラーが検出されると、その try ステートメントに対応する catch ステートメントが実行されます。

finally ステートメントで囲んだステートメントは、 try ブロックでエラーが発生したかどうかに関係なく実行されます。エラーが発生しなかった場合は、 try ブロック内のステートメントが終了した後で、 finally ブロック内のステートメントが実行されます。エラーが発生した場合は、適切な catch ステートメントがまず実行され、その後で finally ブロック内のステートメントが実行されます。

try..catch..finally ステートメントを使用する際のシンタックスを次のコードに示します。

try 
{ 
    // some code that could throw an error 
} 
catch (err:Error) 
{ 
    // code to react to the error 
} 
finally 
{ 
    // Code that runs whether an error was thrown. This code can clean 
    // up after the error, or take steps to keep the application running. 
}

個々の catch ステートメントは、処理する特定の例外の型を指定します。 catch ステートメントが指定できるのは Error クラスのサブクラスのみです。各 catch ステートメントは上から順にチェックされ、スローされたエラーに該当する最初の catch ステートメントだけが実行されます。したがって、先に上位レベルの Error クラスをチェックし、その Error クラスのサブクラスを後からチェックすると、上位レベルの Error クラスに対する処理しか実行されません。この動作を説明するコードを次に示します。

try 
{ 
    throw new ArgumentError("I am an ArgumentError"); 
} 
catch (error:Error) 
{ 
    trace("<Error> " + error.message); 
} 
catch (error:ArgumentError) 
{ 
    trace("<ArgumentError> " + error.message); 
}

上のコードを実行すると、次のように表示されます。

<Error> I am an ArgumentError

ArgumentError を正しくキャッチするには、次のコードのように、最も具体的なエラーのチェックが最初で、下に行くほど一般性の強いエラーのチェックになるような順序にしてください。

try 
{ 
    throw new ArgumentError("I am an ArgumentError"); 
} 
catch (error:ArgumentError) 
{ 
    trace("<ArgumentError> " + error.message); 
} 
catch (error:Error) 
{ 
    trace("<Error> " + error.message); 
}

ActionScript API に含まれるいくつかのメソッドとプロパティでは、実行中にエラーが発生するとランタイムエラーをスローします。例えば、Sound クラスの close() メソッドは、オーディオストリームを閉じることができない場合に IOError をスローします。次にコード例を示します。

var mySound:Sound = new Sound(); 
try 
{ 
    mySound.close(); 
} 
catch (error:IOError) 
{ 
    // Error #2029: This URLStream object does not have an open stream. 
}

Adobe Flash Platform 用 ActionScript 3.0 リファレンスガイド 』をよく読むと、どのメソッドが例外をスローするかがわかります。詳しくは、各メソッドの説明に記載されています。

throw ステートメント

アプリケーションの実行中にエラーが発生すると、Flash ランタイムは例外をスローします。また、アプリケーション内で throw ステートメントを使用すれば、開発者が例外を明示的にスローすることもできます。明示的にエラーをスローした場合は、Error クラスまたはそのサブクラスのインスタンスをスローすることをお勧めします。 次のコードは、Error クラスのインスタンス MyErr をスローする throw ステートメントを示し、最後に、エラーのスロー後に応答するために関数 myFunction() を呼び出しています。

var MyError:Error = new Error("Encountered an error with the numUsers value", 99); 
var numUsers:uint = 0; 
try 
{ 
    if (numUsers == 0) 
    { 
        trace("numUsers equals 0"); 
    } 
} 
catch (error:uint) 
{ 
    throw MyError; // Catch unsigned integer errors. 
} 
catch (error:int) 
{ 
    throw MyError; // Catch integer errors. 
} 
catch (error:Number) 
{ 
    throw MyError; // Catch number errors. 
} 
catch (error:*) 
{ 
    throw MyError; // Catch any other error. 
} 
finally  
{ 
    myFunction(); // Perform any necessary cleanup here. 
}

このように、 catch ステートメントは最も限定的なデータ型から順に記述してください。Number データ型に対する catch ステートメントを最初に記述した場合、uint データ型や int データ型に対する catch ステートメントは実行されません。

注意: Java プログラミング言語では、例外をスローする可能性があるすべての関数はその旨を宣言することが義務付けられています。宣言するには、スローする可能性がある例外クラスを列挙した throws 節を関数の宣言に含めます。ActionScript では、関数がスローする例外を宣言する必要はありません。

単純なエラーメッセージの表示

新しい例外およびエラーイベントモデルがもたらす最大のメリットの 1 つに、アクションが失敗したタイミングと理由をユーザーに示すことができるという点があります。 コードを記述する際、メッセージの表示と応答オプションの提示があるようにします。

次のコードは、エラーをテキストフィールドに表示する単純な try..catch ステートメントを示しています。

package 
{ 
    import flash.display.Sprite; 
    import flash.text.TextField; 
     
    public class SimpleError extends Sprite 
    { 
        public var employee:XML =  
            <EmpCode> 
                <costCenter>1234</costCenter> 
                <costCenter>1-234</costCenter> 
            </EmpCode>; 
 
        public function SimpleError() 
        { 
            try 
            { 
                if (employee.costCenter.length() != 1) 
                { 
                    throw new Error("Error, employee must have exactly one cost center assigned."); 
                } 
            }  
            catch (error:Error) 
            { 
                var errorMessage:TextField = new TextField(); 
                errorMessage.autoSize = TextFieldAutoSize.LEFT; 
                errorMessage.textColor = 0xFF0000; 
                errorMessage.text = error.message; 
                addChild(errorMessage); 
            } 
        } 
    } 
}

広範囲のエラークラスおよびビルトインのコンパイルエラーを使用することで、ActionScript 3.0 では以前のバージョンの ActionScript に比べ、何かが失敗したときにその理由に関してより多くの情報が提供されます。 この情報により、エラー処理に優れ、安定性の向上したアプリケーションを構築できます。

エラーの再スロー

アプリケーションの開発時には、エラーを適切に処理できない場合にエラーを再スローする必要が生じることがあります。例えば、次のコードはネストされた try..catch ブロックを示し、ネストされた catch ブロックでエラーを処理できない場合には独自の ApplicationError を再スローします。

try 
{ 
    try 
    { 
        trace("<< try >>"); 
        throw new ApplicationError("some error which will be rethrown"); 
    } 
    catch (error:ApplicationError) 
    { 
        trace("<< catch >> " + error); 
        trace("<< throw >>"); 
        throw error; 
    } 
    catch (error:Error) 
    { 
        trace("<< Error >> " + error); 
    } 
} 
catch (error:ApplicationError) 
{ 
    trace("<< catch >> " + error); 
}

このコードを実行すると次のような内容が表示されます。

<< try >> 
<< catch >> ApplicationError: some error which will be rethrown 
<< throw >> 
<< catch >> ApplicationError: some error which will be rethrown

ネストされた try ブロックで独自の ApplicationError エラーをスローすると、それに続く catch ブロックがエラーをキャッチします。このネストされた catch ブロックではエラー処理を試みますが、処理できない場合は ApplicationError オブジェクトを上位の try..catch ブロックに対してスローします。