Bug 1102477: pass HAWK request errors through to content. r=Standard8
authorMike de Boer <mdeboer@mozilla.com>
Wed, 07 Jan 2015 16:44:50 +0100
changeset 222419 d350cd94c55177c0abe93c4f88aa76765d355cd7
parent 222418 cf3485c7753bdc44d0cfd8a14aadf570af2d8660
child 222420 1bc77d8c8681293b7baed676753f16e691dc0bd4
push id10685
push usermdeboer@mozilla.com
push dateWed, 07 Jan 2015 15:46:55 +0000
treeherderfx-team@d350cd94c551 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1102477
milestone37.0a1
Bug 1102477: pass HAWK request errors through to content. r=Standard8
browser/components/loop/MozLoopAPI.jsm
--- a/browser/components/loop/MozLoopAPI.jsm
+++ b/browser/components/loop/MozLoopAPI.jsm
@@ -38,23 +38,33 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                          "nsIExternalProtocolService");
 this.EXPORTED_SYMBOLS = ["injectLoopAPI"];
 
 /**
  * Trying to clone an Error object into a different container will yield an error.
  * We can work around this by copying the properties we care about onto a regular
  * object.
  *
- * @param {Error}        error        Error object to copy
- * @param {nsIDOMWindow} targetWindow The content window to attach the API
+ * @param {Error|nsIException} error        Error object to copy
+ * @param {nsIDOMWindow}       targetWindow The content window to clone into
  */
 const cloneErrorObject = function(error, targetWindow) {
   let obj = new targetWindow.Error();
-  for (let prop of Object.getOwnPropertyNames(error)) {
+  let props = Object.getOwnPropertyNames(error);
+  // nsIException properties are not enumerable, so we'll try to copy the most
+  // common and useful ones.
+  if (!props.length) {
+    props.push("message", "filename", "lineNumber", "columnNumber", "stack");
+  }
+  for (let prop of props) {
     let value = error[prop];
+    // for nsIException objects, the property may not be defined.
+    if (typeof value == "undefined") {
+      continue;
+    }
     if (typeof value != "string" && typeof value != "number") {
       value = String(value);
     }
 
     Object.defineProperty(Cu.waiveXrays(obj), prop, {
       configurable: false,
       enumerable: true,
       value: value,
@@ -73,26 +83,31 @@ const cloneErrorObject = function(error,
  * @param {any}          value        Value or object to copy
  * @param {nsIDOMWindow} targetWindow The content window to copy to
  */
 const cloneValueInto = function(value, targetWindow) {
   if (!value || typeof value != "object") {
     return value;
   }
 
+  // HAWK request errors contain an nsIException object inside `value`.
+  if (("error" in value) && (value.error instanceof Ci.nsIException)) {
+    value = value.error;
+  }
+
   // Strip Function properties, since they can not be cloned across boundaries
   // like this.
   for (let prop of Object.getOwnPropertyNames(value)) {
     if (typeof value[prop] == "function") {
       delete value[prop];
     }
   }
 
   // Inspect for an error this way, because the Error object is special.
-  if (value.constructor.name == "Error") {
+  if (value.constructor.name == "Error" || value instanceof Ci.nsIException) {
     return cloneErrorObject(value, targetWindow);
   }
 
   let clone;
   try {
     clone = Cu.cloneInto(value, targetWindow);
   } catch (ex) {
     MozLoopService.log.debug("Failed to clone value:", value);