Bug 1263747 - Log error messages when stringifying errors. r=bgrins
authorKit Cambridge <kcambridge@mozilla.com>
Mon, 11 Apr 2016 14:51:33 -0700
changeset 331063 ea4c6f1f0ff00638fdba1fbc11f0b3f3922e9260
parent 331062 1bce3f1720e66a9cdc1a1699d3fd24a598641969
child 331064 7d08ffc48bac5c2f9a8c97f9d2b7d9677651e0af
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins
bugs1263747
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1263747 - Log error messages when stringifying errors. r=bgrins MozReview-Commit-ID: 2MB8IDKfVHo
dom/push/PushService.jsm
toolkit/modules/Console.jsm
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -1068,17 +1068,17 @@ this.PushService = {
    * Exceptions thrown in _onRegisterError are caught by the promise obtained
    * from _service.request, causing the promise to be rejected instead.
    */
   _onRegisterError: function(reply) {
     console.debug("_onRegisterError()");
     Services.telemetry.getHistogramById("PUSH_API_SUBSCRIBE_FAILED").add()
     if (!reply.error) {
       console.warn("onRegisterError: Called without valid error message!",
-        reply, String(reply));
+        reply);
       throw new Error("Registration error");
     }
     throw reply.error;
   },
 
   notificationsCleared() {
     this._visibleNotifications.clear();
   },
--- a/toolkit/modules/Console.jsm
+++ b/toolkit/modules/Console.jsm
@@ -101,16 +101,31 @@ function getCtorName(aObj) {
     return aObj.constructor.name;
   }
   // If that fails, use Objects toString which sometimes gives something
   // better than 'Object', and at least defaults to Object if nothing better
   return Object.prototype.toString.call(aObj).slice(8, -1);
 }
 
 /**
+ * Indicates whether an object is a JS or `Components.Exception` error.
+ *
+ * @param {object} aThing
+          The object to check
+ * @return {boolean}
+          Is this object an error?
+ */
+function isError(aThing) {
+  return aThing && (
+           (typeof aThing.name == "string" &&
+            aThing.name.startsWith("NS_ERROR_")) ||
+           getCtorName(aThing).endsWith("Error"));
+}
+
+/**
  * A single line stringification of an object designed for use by humans
  *
  * @param {any} aThing
  *        The object to be stringified
  * @param {boolean} aAllowNewLines
  * @return {string}
  *        A single line representation of aThing, which will generally be at
  *        most 80 chars long
@@ -119,16 +134,20 @@ function stringify(aThing, aAllowNewLine
   if (aThing === undefined) {
     return "undefined";
   }
 
   if (aThing === null) {
     return "null";
   }
 
+  if (isError(aThing)) {
+    return "Message: " + aThing;
+  }
+
   if (typeof aThing == "object") {
     let type = getCtorName(aThing);
     if (aThing instanceof Components.interfaces.nsIDOMNode && aThing.tagName) {
       return debugElement(aThing);
     }
     type = (type == "Object" ? "" : type + " ");
     let json;
     try {
@@ -198,19 +217,17 @@ function log(aThing) {
     else if (type == "Set") {
       let i = 0;
       reply += "Set\n";
       for (let value of aThing) {
         reply += logProperty('' + i, value);
         i++;
       }
     }
-    else if (type.match("Error$") ||
-             (typeof aThing.name == "string" &&
-              aThing.name.match("NS_ERROR_"))) {
+    else if (isError(aThing)) {
       reply += "  Message: " + aThing + "\n";
       if (aThing.stack) {
         reply += "  Stack:\n";
         var frame = aThing.stack;
         while (frame) {
           reply += "    " + frame + "\n";
           frame = frame.caller;
         }