如何捕获Flex中的所有异常?
-
01-07-2019 - |
题
当我在调试 Flash 播放器中运行 Flex 应用程序时,一旦发生意外情况,就会弹出异常。然而,当客户使用该应用程序时,他不会使用调试闪存播放器。在这种情况下,他不会弹出异常,但他的 UI 无法正常工作。
因此,出于可支持性的原因,我希望捕获 Flex UI 中任何地方可能发生的任何异常,并在 Flex 内部弹出窗口中显示错误消息。通过使用 Java,我只需将整个 UI 代码封装在 try/catch 块中,但对于 Flex 中的 MXML 应用程序,我不知道在哪里可以执行这样的常规 try/catch。
解决方案
Flex 3 中无法通知未捕获的异常。Adobe 已经意识到这个问题,但我不知道他们是否计划创建解决方法。
目前唯一的解决方案是将 try/catch 放在逻辑位置,并确保您正在侦听调度它们的任何事件的 ERROR(或 Web 服务的 FAULT)事件。
编辑: 此外,实际上不可能捕获事件处理程序抛出的错误。我已经登录了 漏洞 在 Adobe Bug 系统上。
2010年1月12日更新: 现在支持全局错误处理 闪存10.1 和 空气2.0 (均处于测试版),并通过订阅来实现 未捕获的错误 的事件 LoaderInfo.uncaughtErrorEvents. 。以下代码摘自 livedocs 上的代码示例:
public class UncaughtErrorEventExample extends Sprite
{
public function UncaughtErrorEventExample()
{
loaderInfo.uncaughtErrorEvents.addEventListener(
UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
}
private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
{
if (event.error is Error)
{
var error:Error = event.error as Error;
// do something with the error
}
else if (event.error is ErrorEvent)
{
var errorEvent:ErrorEvent = event.error as ErrorEvent;
// do something with the error
}
else
{
// a non-Error, non-ErrorEvent type was thrown and uncaught
}
}
其他提示
Adobe 错误管理系统中存在对此的错误/功能请求。如果它对您很重要,请投票。
它适用于 Flex 3.3。
if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){
IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", uncaughtErrorHandler);
}
请注意,错误 FP-444(上面)链接到 http://labs.adobe.com/technologies/flashplayer10/features.html#developer 自 2009 年 10 月以来,这表明从 10.1 开始这将是可能的,目前,2009 年 10 月 28 日尚未发布 - 所以我想我们会在发布时看看这是否属实
使用 try-catch 替代已接受的答案。我认为速度较慢,但更容易阅读。
try {
loaderInfo.uncaughtErrorEvents.addEventListener("uncaughtError", onUncaughtError);
} catch (e:ReferenceError) {
var spl:Array = Capabilities.version.split(" ");
var verSpl:Array = spl[1].split(",");
if (int(verSpl[0]) >= 10 &&
int(verSpl[1]) >= 1) {
// This version is 10.1 or greater - we should have been able to listen for uncaught errors...
d.warn("Unable to listen for uncaught error events, despite flash version: " + Capabilities.version);
}
}
当然,您需要使用最新的 10.1 playerglobal.swc 才能成功编译此代码:http://labs.adobe.com/downloads/flashplayer10.html
我正在使用 Flex 4。我试过 loaderInfo.UncaughtErrorEvents,
但 loaderInfo 未初始化,因此它给了我空引用错误。然后我尝试了 root.loaderInfo.UncaughtErrorEvents
和同一个故事。我试过 sprite.root.UncaughtErrorEvents
, ,但是没有精灵对象,我创建了一个,但它不起作用。最后我尝试了
systemManager.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,globalUnCaughtErrorHandler.hanleUnCaughtError);
你猜怎么着,它就像魔术一样起作用。查看 这
它适用于 Flex 3.5 和 Flash Player 10:
<?xml version="1.0" encoding="utf-8"?>
protected function application1_addedToStageHandler(event:Event):void{
if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){
IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", uncaughtErrorHandler);
}
sdk.text = "Flex " + mx_internal::VERSION;
}
private function uncaughtErrorHandler(e:*):void{
e.preventDefault();
var s:String;
if (e.error is Error)
{
var error:Error = e.error as Error;
s = "Uncaught Error: " + error.errorID + ", " + error.name + ", " + error.message;
}
else
{
var errorEvent:ErrorEvent = e.error as ErrorEvent;
s = "Uncaught ErrorEvent: " + errorEvent.text;
}
msg.text = s;
}
private function unCaught():void
{
var foo:String = null;
trace(foo.length);
}
]]>
</mx:Script>
<mx:VBox>
<mx:Label id="sdk" fontSize="18"/>
<mx:Button y="50" label="UnCaught Error" click="unCaught();" />
<mx:TextArea id="msg" width="180" height="70"/>
</mx:VBox>
谢谢
我将事件侦听器附加到“根”,这对我有用:
sprite.root.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
在调试 Flash Player 中,这仍然会出错,但在非调试版本中,错误将出现在 Flash Player 的对话框中 - 然后处理程序将做出响应。要停止出现该对话框,请添加:
event.preventDefault();
所以:
private function onUncaughtError(event:UncaughtErrorEvent):void
{
event.preventDefault();
// do something with this error
}
我在 AIR 中使用了它,但我认为它也适用于标准 AS3 项目。
现在您可以使用加载程序信息:
http://www.adobe.com/devnet/flex/articles/global-exception-handling.html
查看:loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
private function onUncaughtError(e:UncaughtErrorEvent):void
{
// Do something with your error.
}