Refactored the exception-handling code a bit and made traces produced by async look more like they used to.

This commit is contained in:
Atul Varma 2008-07-01 12:03:05 -07:00
parent 0013cac9d2
commit 7303b375dc
2 changed files with 36 additions and 32 deletions

View File

@ -119,11 +119,7 @@ function Generator(thisArg, method, onComplete, args) {
gOutstandingGenerators.add(this);
this._initFrame = Components.stack.caller;
// skip our frames
// FIXME: we should have a pref for this, for debugging async.js itself
while (this._initFrame.name.match(/^Async(Gen|)_/))
this._initFrame = this._initFrame.caller;
this._initFrame = skipAsyncFrames(Components.stack.caller);
}
Generator.prototype = {
get name() { return this._method.name + "-" + this._id; },
@ -178,8 +174,11 @@ Generator.prototype = {
if (this._stackAtLastCallbackGen)
cbGenText = (" (last self.cb generated at " +
formatAsyncFrame(this._stackAtLastCallbackGen) + ")");
let frame = skipAsyncFrames(this._initFrame);
return ("unknown (async) :: " + this.name + cbGenText + "\n" +
traceAsyncFrame(this._initFrame));
Utils.stackTraceFromFrame(frame, formatAsyncFrame));
},
_handleException: function AsyncGen__handleException(e) {
@ -206,7 +205,7 @@ Generator.prototype = {
this._log.warn("Exception: " + Utils.exceptionStr(e));
} else {
this._log.error("Exception: " + Utils.exceptionStr(e));
this._log.debug("Stack trace:\n" + Utils.stackTrace(e));
this._log.debug("Stack trace:\n" + Utils.stackTrace(e, formatAsyncFrame));
}
// continue execution of caller.
@ -301,7 +300,8 @@ Generator.prototype = {
this._log.error("Exception caught from onComplete handler of " +
this.name + " generator");
this._log.error("Exception: " + Utils.exceptionStr(e));
this._log.trace("Current stack trace:\n" + Utils.stackTrace(e));
this._log.trace("Current stack trace:\n" +
Utils.stackTrace(e, formatAsyncFrame));
this._log.trace("Initial async stack trace:\n" + this.asyncStack);
}
}
@ -309,6 +309,12 @@ Generator.prototype = {
}
};
function skipAsyncFrames(frame) {
while (frame.name && frame.name.match(/^Async(Gen|)_/))
frame = frame.caller;
return frame;
}
function formatAsyncFrame(frame) {
// FIXME: sort of hackish, might be confusing if there are multiple
// extensions with similar filenames
@ -319,23 +325,6 @@ function formatAsyncFrame(frame) {
return tmp;
}
function traceAsyncFrame(frame, str) {
if (!str)
str = "";
// skip our frames
// FIXME: we should have a pref for this, for debugging async.js itself
while (frame.name && frame.name.match(/^Async(Gen|)_/))
frame = frame.caller;
if (frame.caller)
str = traceAsyncFrame(frame.caller, str);
str = formatAsyncFrame(frame) + (str? "\n" : "") + str;
return str;
}
Async = {
get outstandingGenerators() { return gOutstandingGenerators; },

View File

@ -218,17 +218,32 @@ let Utils = {
return message + location;
},
stackTrace: function Weave_stackTrace(e) {
stackTraceFromFrame: function Weave_stackTraceFromFrame(frame, formatter) {
if (!formatter)
formatter = function defaultFormatter(frame) { return frame; };
let output = "";
while (frame) {
output += formatter(frame) + "\n";
frame = frame.caller;
}
return output;
},
stackTrace: function Weave_stackTrace(e, formatter) {
let output = "";
if (e.location) {
// It's a wrapped nsIException.
let frame = e.location;
while (frame) {
output += frame + "\n";
frame = frame.caller;
}
output += this.stackTraceFromFrame(e.location, formatter);
} else if (e.stack)
// It's a standard JS exception
// It's a standard JS exception.
// TODO: It would be nice if we could parse this string and
// create a 'fake' nsIStackFrame-like call stack out of it,
// so that we can do things w/ this stack trace like we do
// with nsIException traces.
output += e.stack;
else
// It's some other thrown object, e.g. a bare string.