AS3从事件回调报告错误

时间:2011-08-17 09:14:13

标签: actionscript-3 debugging actionscript asynchronous event-handling

当AS3中的异步代码发生错误时,我一直在尝试提供更好的调试信息。

作为默认错误报告的一个例子,假设我在Timer回调(github gist)中强制使用空指针,我在控制台上得到以下堆栈跟踪:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at Function/<anonymous>()[/[path-to-source-file]/TestClass.as:14]
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()

这告诉我很少关于计时器回调实际上如何链接到我的代码。

问题是:如何获取有关创建回调的代码的信息?

我在下面添加了一个解决方案。我很想知道这是否可以改进。

3 个答案:

答案 0 :(得分:0)

一种可能的解决方案是在消费者“线程”/“范围”

中预先创建一个Error对象
        var errorInConsumerScope:Error = new Error()

        var timer:Timer = new Timer(1000, 1)
        timer.addEventListener(TimerEvent.TIMER, internalCallback)
        timer.start()

        function internalCallback(e:TimerEvent):void 
        {
            try
            {
                // do something that could cause an error
            }
            catch (e:Error)
            {
                errorInConsumerScope.message = e.message
                throw errorInConsumerScope
            }
        }

这现在让我将堆栈跟踪返回到我的调用代码中:

Error: Error #1009: Cannot access a property or method of a null object reference.
    at TestClass()[/[path-to-source-file]/TestClass.as:10]
    at Main()[/[path-to-source-file]/Main.as:9]

完整的要点是here

答案 1 :(得分:0)

有趣的事情。

The doc to Error.getStackTrace() says

  

将错误的调用堆栈作为字符串返回   错误的构造

据此,堆栈跟踪按预期工作。错误是在事件处理程序中构造的,由timer tick事件调用。

在第二个示例中,您将创建要在TestClass的构造函数中调度的错误。所以你的stacktrace将显示到TestClass构造函数的链。

答案 2 :(得分:0)

您可能会要求一般解决方案。我会使用断点和对象检查进行单元测试和适当的调试。但这里有另一个想法:

识别TestClass:

package {
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    public class TestClass {
        public function TestClass(userCallback : Function, fail : Function) {
            var timer : Timer = new Timer(1000, 1);
            timer.addEventListener(TimerEvent.TIMER, internalCallback);
            timer.start();

            function internalCallback(e : TimerEvent):void {
                try {
                    var nullProperty : String;
                    nullProperty.length;
                } catch (e:Error) {
                    fail();
                    return;
                }
                userCallback();
            }
        }
    }
}

主:

package {
    import flash.display.Sprite;

    public class Main extends Sprite {
        public function Main() {
            new TestClass(
                function() : void { trace('Call me back when your done.'); },
                function() : void { throw new Error('Something went wrong.'); }
            );
        }
    }
}

输出:

Exception fault: Error: Something went wrong.
    at Function/<anonymous>()[Main.as:8]
    at Function/TestClass/$construct/internalCallback()[TestClass.as:16]
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()