守望者--AIR技术交流

标题: 软件发行版捕获全局异常日志的方法 [打印本页]

作者: 破晓    时间: 2015-1-5 17:52
标题: 软件发行版捕获全局异常日志的方法
最近游戏快上线了。老板提了个需求。希望我们能把客户端的报错都记录下来,并存到服务器日志里。有很多线上的bug,在本地很难重现,如果能记录下来报错地方的调用堆栈。对调试就会很有帮助。也可以更加准确地分析出用户的留存率是否跟某个bug有关系,从而及时修复。
查了下API,loaderInfo有个uncaughtErrorEvents的属性,可以在上面监听到全局未处理(没有在try…catch里)的异常。这个接口是FP10.1开始提供的。现在FP一般都是11以上了。所以应该没问题。写了下代码,测试成功。可是遇到个问题,没法获取异常触发地点的调用堆栈。因为Error.getStackTrace()方法(FP9已经提供)被限制在Debug版本中使用。后来经高人指点,FP11.5以上版本又开放了这个接口,可以在非Debug版FP中调用了。据最新的统计数据显示,FP11的覆盖率应该已经达到80%以上,而且FP11以后都有静默升级。也就是说大部分用户都是在11.5以上版本的。写这个功能也只是做辅助的调试日志用,有这个覆盖率应该足够了。不过,要开启这个接口,必须在编译时加上编译参数-swf-version=18,否则,即使客户端FP版本够高也不会为你的SWF文件开启这个接口。经过反复测试。增加-swf-version=18并不会导致SWF不能在低版本的FP上运行。所以是兼容的。
以下是测试代码:
ErrorTest.as
  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.events.ErrorEvent;
  5.     import flash.events.UncaughtErrorEvent;
  6.     import flash.text.TextField;
  7.     import flash.utils.setTimeout;

  8.     import org.domlib.test.ErrorDispatcher;

  9.     /**
  10.      * 全局异常捕获测试
  11.      * @author DOM
  12.      */
  13.     public class ErrorTest extends Sprite
  14.     {
  15.         public function ErrorTest()
  16.         {
  17.             loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,unCaughtErrorHandler);
  18.             logText.width = logText.height = 1000;
  19.             addChild(logText);
  20.             setTimeout(runTest,20);
  21.         }

  22.         private var logText:TextField = new TextField();

  23.         private function runTest():void
  24.         {
  25.             try
  26.             {
  27.                 new ErrorDispatcher("在try...catch里的错误");//在try...catch里的错误不会触发事件。
  28.             }
  29.             catch(e:Error){}

  30.             new ErrorDispatcher("不在try...catch里的错误");//这个错误会触发。
  31.         }

  32.         private function unCaughtErrorHandler(event:UncaughtErrorEvent):void
  33.         {
  34.             var message:String = "";
  35.             if(event.error is Error)
  36.             {
  37.                 //只有FP11.5以上才能在非debug版本中调用getStackTrace()。
  38.                 message = Error(event.error).getStackTrace();
  39.                 if(!message)
  40.                     message = Error(event.error).message;

  41.             }
  42.             else if(event.error is ErrorEvent)
  43.             {
  44.                 message = ErrorEvent(event.error).text;
  45.             }
  46.             else
  47.             {
  48.                 message = event.error.toString();
  49.             }
  50.             logText.appendText(message);
  51.         }
  52.     }
  53. }
复制代码
ErrorDispatcher.as
  1. package org.domlib.test
  2. {

  3.     /**
  4.      * 错误抛出者
  5.      * @author DOM
  6.      */
  7.     public class ErrorDispatcher
  8.     {
  9.         public function ErrorDispatcher(message:String)
  10.         {
  11.             throw new Error(message);
  12.         }
  13.     }
  14. }
复制代码
运行结果:

[attach]199[/attach]

[attach]200[/attach]

这里要注意下,测试的时候要导出发行版,然后用非Debug版本的FP去运行,Debug版本的FP设不设置swf-version=18,都能成功获得堆栈信息。

本文来自:http://blog.domlib.com/articles/475.html






欢迎光临 守望者--AIR技术交流 (http://www.airmyth.com/)