当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()
这告诉我很少关于计时器回调实际上如何链接到我的代码。
问题是:如何获取有关创建回调的代码的信息?
我在下面添加了一个解决方案。我很想知道这是否可以改进。
答案 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()