處理應用程式中的同步錯誤

最常用的錯誤處理程序是同步錯誤處理邏輯,也就是將陳述式插入程式碼,在執行階段捕捉同步錯誤。這種類型的錯誤處理方式可以讓您的應用程式在功能失敗時,注意到執行階段錯誤並加以復原。捕捉同步錯誤的邏輯包括 try..catch..finally 陳述式,此陳述式基本上會重複嘗試執行作業、捕捉來自 Flash Player 的錯誤回應,最後再執行部分其它作業以處理失敗的作業。

副主題

使用 try..catch..finally 陳述式
throw 陳述式
顯示簡單的錯誤訊息
重新擲回錯誤

使用 try..catch..finally 陳述式

當您在處理同步執行階段錯誤時,請使用 try..catch..finally 陳述式來捕捉錯誤。一旦發生執行階段錯誤,Flash Player 就會擲回例外,也就是說,Flash Player 會暫停正常的執行作業,並建立類型為 Error 的特殊物件。接著該 Error 物件會擲向第一個可用的 catch 區塊。

try 陳述式包含可能會造成錯誤的陳述式。使用 catch 陳述式時,請務必搭配 try 陳述式。如果在 try 陳述式區塊的其中一個陳述式內偵測到錯誤,附加在 try 陳述式的 catch 陳述式就會執行。

不管 try 區塊中是否發生錯誤,finally 陳述式中都包含將會執行的陳述式。如果沒有錯誤,finally 區域中的陳述式就會在 try 區塊陳述式完成後執行。如果有錯誤,則會先執行適當的 catch 陳述式,接著再執行 finally 區塊中的陳述式。

下列程式碼將示範 try..catch..finally 陳述式的使用語法:

try
{
   // 有些程式碼可能擲回錯誤
}
catch (err:Error)
{
   // 程式碼以回應錯誤
}
finally
{
   // 不論是否擲回錯誤都會執行的程式碼。此程式碼會在錯誤後清理,
    // 或是採取步驟,讓應用程式繼續執行。
}

每個 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);
}

Flash Player API 中的幾個方法和屬性如果在執行時遇到錯誤,則會擲回執行階段錯誤。例如,當 Sound 類別中的 close() 方法無法關閉聲音串流時,便會擲回 IOError,如下列程式碼所示:

var mySound:Sound = new Sound();
try
{
    mySound.close();
}
catch (error:IOError)
{
    // 錯誤 #2029:此 URLStream 物件沒有開放式串流。
}

當您更熟悉ActionScript 3.0 語言和組件參考之後,就會注意到哪些方法會擲回例外,如每種方法的說明所述。

throw 陳述式

在執行階段,當 Flash Player 遇到應用程式中的錯誤時,就會擲回例外。另外,您本身也可以使用 throw 陳述式明確擲回例外。明確擲出錯誤時,Adobe 建議您擲回 Error 類別或是其子類別的實體。下列程式碼將示範 throw 陳述式擲回 Error 類別 MyErr 的實體,最後並在擲回錯誤後,呼叫函數 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 (error:int)
{
    throw MyError; // 捕捉整數錯誤。
}
catch (error:Number)
{
    throw MyError; // 捕捉數字錯誤。
}
catch (error:*)
{
    throw MyError; // 捕捉任何其它錯誤。
}
finally 
{
    myFunction(); // 在此執行任何必要的清理。
}

請注意,catch 陳述式是依序排列的,因此最明確的資料類型會排在第一。如果 Number 資料類型的 catch 陳述式排在第一,則 uint 資料類型的 catch 陳述式和 int 資料類型的 catch 陳述式都不會執行。

注意

 

在 Java 程式語言中,每個可以擲回例外的函數都必須宣告這項事實,並將它可以擲回的例外類別,列在附加於函數宣告的 throws 子句中。ActionScript 並不會要求您宣告函數所能擲回的例外。

顯示簡單的錯誤訊息

新的例外和錯誤事件模型的最大好處之一,就是能夠讓您告訴使用者,動作失敗的時間和原因。您的責任是撰寫程式碼以顯示訊息,並提供回應的選項。

下列程式碼將顯示簡單的 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 ArgumentError("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 區塊。


Flash CS3

 

有新的意見加入至這個頁面時,傳送電子郵件給我 | 意見報告

目前頁面: http://livedocs.adobe.com/flash/9.0_tw/main/00000102.html