在应用程序中处理同步错误

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

最常见的错误处理是同步错误处理逻辑,您可以在处理逻辑中将适当的语句插入代码,以便在应用程序运行时捕获同步错误。这种错误处理可以让应用程序在功能失败时注意到发生运行时错误并从错误中恢复。同步错误捕获逻辑包括 try..catch..finally 语句,从字面意义上看,这种方式先尝试 (try) 某个操作,然后捕获 (catch) 来自 Flash 运行时的任何错误响应,最后 (finally) 执行另外的操作来处理失败的操作。

使用 try..catch..finally 语句

处理同步运行时错误时,可以使用 try..catch..finally 语句来捕获错误。当发生运行时错误时,Flash 运行时将引发异常,这意味着它将暂停正常的操作而创建一个 Error 类型的特殊对象。Error 对象随后会被引发到第一个可用的 catch 块。

try 语句将有可能产生错误的语句括在一起。 catch 语句应始终与 try 语句一起使用。如果在 try 语句块的其中一个语句中检测到错误,则将运行附加到该 try 语句的 catch 语句。

finally 语句中包含无论 try 块中是否出错均会运行的语句。如果没有错误, finally 块中的语句将在 try 语句块执行完毕之后执行。如果有错误,则首先执行相应的 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 语句明确引发异常。如果是明确引发错误,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 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 编程语言中,每个可以引发异常的函数都必须先声明这一点,并在附加到函数声明的 throw 子句中列出该函数可以引发的异常类。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 的先前版本相比,ActionScript 3.0 使用了更加丰富的错误类和内置编译器错误,因此可以提供有关失败原因的更多信息。通过此信息,您可以构建更加稳定且具有更佳错误处理能力的应用程序。

重新引发错误

构建应用程序时,有时候,如果无法正确处理错误,则需要重新引发该错误。例如,以下代码使用一个嵌套的 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 对象引发到包含此 catch 块的 try..catch 块中来进行处理。