From 324ad97fb0ba00499d15165944c16bd373a1560d Mon Sep 17 00:00:00 2001 From: Atul Varma Date: Tue, 1 Jul 2008 12:03:05 -0700 Subject: [PATCH] Refactored the exception-handling code a bit and made traces produced by async look more like they used to. --- services/sync/modules/async.js | 39 ++++++++++++---------------------- services/sync/modules/util.js | 29 +++++++++++++++++++------ 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/services/sync/modules/async.js b/services/sync/modules/async.js index 685aaf691078..ef7fe4acc7f8 100644 --- a/services/sync/modules/async.js +++ b/services/sync/modules/async.js @@ -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; }, diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index 52079f0f20da..dcaafa6f39f3 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -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.