代码改变世界

耍了一下 UncaughtErrorEvents

2010-06-12 18:28  hbb  阅读(1166)  评论(2)    收藏  举报

玩了一下UncaughtErrorEvents,发现没有想象中神奇。

首先是编译器比较2,不支持例子中的代码,还要hack一下。

然后是实际效果了,本来以为加了全局错误处理,就可以把错误销匿于无形。这话的两说,如果Release版本倒确实如此,不过Release版本的话,本来也看不出什么反应,如果是Debug版本,那个讨厌的框框还是会弹出来的。也就是说,Debug版本那个框执行的顺序优先于UncaughtError的处理函数。

最后发现是自己想的太美好,而且不注重错误处理,竟然把Adobe实现的这么NB的功能,想成主要是用来藏匿框框,实在不应该。

 

 

于是仔细阅读了帮助,发现有以下几个特点。

第一,该事件可以加在两个地方,一个是LoaderInfo,一个是Loader。以一个swf为一个对象的话,前者用来监听自身的所有未捕捉的错误,后者用来监听被加载对象的未捕捉错误。

第二,Flash9以前的老版本swf,以及页面对象(Flex,AIR)中出现的未捕捉错误,不受控制。

第三,处理函数中,如果又报错,不会产生递归调用。

第四,如果不想看到Debug版本中那个烦人的弹出框,需要在函数内写上e.preventDefault();

 

以下是临时用测试代码...

 

package  
{
	import flash.display.*;
	import flash.events.*;
	import flash.net.URLRequest;
	import flash.text.TextField;
	
	
	public class GlobalErrorHandling extends Sprite
	{
		
		public function GlobalErrorHandling() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		private function onAddedToStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			init();
		}
		
		private function init():void
		{
			if (!loaderInfo.hasOwnProperty('uncaughtErrorEvents')) return;
			
			loaderInfo['uncaughtErrorEvents'].addEventListener('uncaughtError', onUncaughtError);
			
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}
		
		private function onClick(e:MouseEvent):void 
		{
			var foo:Number = Math.random();
			switch(true)
			{
				case (foo > .7) : throw new Error('Wow!'); break;
				case (foo > .5) : throw new ArgumentError('Kak!'); break;
				case (foo > .2) : throw "String Exception"; break;
				case (foo > .0) : new Loader().load(new URLRequest('noexist.swf')); break;
			}
		}
		
		private function onUncaughtError(e:*):void 
		{
			e.preventDefault();
			var message:String;
			switch(true)
			{
				case (e.error is Error): 		message = Error(e.error).message;			break;
				case (e.error is ErrorEvent):	message = ErrorEvent(e.error).text;			break;
				default:				message = e.error.toString();				break;
			}
			
			log(message);
			
			throw "Error In UncaughtError Handler!";
			
			log('I am invisiable man');
		}
		
		private function log(msg:String):void
		{
			if (getChildByName('logTxt') is TextField)
			{
				TextField(getChildByName('logTxt')).appendText(msg + '\n');
				TextField(getChildByName('logTxt')).scrollV = TextField(getChildByName('logTxt')).maxScrollV;
				return;
			}
			
			var txt:TextField = new TextField();
			txt.name = 'logTxt';
			txt.width = 500;
			txt.height = 400;
			txt.x = txt.y = 100;
			txt.text = '';
			addChild(txt);
		}
		
	}

}