Bug 1215502: Perform nsIException instance test for XPCOM exceptions
The current test of the `result' property does not always pass for all
types of XPCOM exceptions. A safer test is to do an instance check
against Components.interfaces.nsIException.
This fixes hangs such as the one described in
bug 1202576.
r=dburns
--- a/testing/marionette/error.js
+++ b/testing/marionette/error.js
@@ -1,15 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-var {results: Cr, utils: Cu} = Components;
+var {interfaces: Ci, utils: Cu} = Components;
const errors = [
"ElementNotAccessibleError",
"ElementNotVisibleError",
"InvalidArgumentError",
"InvalidElementStateError",
"InvalidSelectorError",
"InvalidSessionIdError",
@@ -26,53 +26,33 @@ const errors = [
"UnknownCommandError",
"UnknownError",
"UnsupportedOperationError",
"WebDriverError",
];
this.EXPORTED_SYMBOLS = ["error"].concat(errors);
-// Because XPCOM is a cesspool of undocumented odd behaviour,
-// Object.getPrototypeOf(err) causes another exception if err is an XPCOM
-// exception, and cannot be used to determine if err is a prototypal Error.
-//
-// Consequently we need to check for properties in its prototypal chain
-// (using in, instead of err.hasOwnProperty because that causes other
-// issues).
-//
-// Since the input is arbitrary it might _not_ be an Error, and can as
-// such be an object with a "result" property without it being considered to
-// be an exception. The solution is to build a lookup table of XPCOM
-// exceptions from Components.results and check if the value of err#results
-// is in that table.
-const XPCOM_EXCEPTIONS = [];
-{
- for (let prop in Cr) {
- XPCOM_EXCEPTIONS.push(Cr[prop]);
- }
-}
-
this.error = {};
/**
* Checks if obj is an instance of the Error prototype in a safe manner.
* Prefer using this over using instanceof since the Error prototype
- * isn't unique across browsers, and XPCOM exceptions are special
+ * isn't unique across browsers, and XPCOM nsIException's are special
* snowflakes.
*
* @param {*} val
* Any value that should be undergo the test for errorness.
* @return {boolean}
* True if error, false otherwise.
*/
error.isError = function(val) {
if (val === null || typeof val != "object") {
return false;
- } else if ("result" in val && val.result in XPCOM_EXCEPTIONS) {
+ } else if (val instanceof Ci.nsIException) {
return true;
} else {
return Object.getPrototypeOf(val) == "Error";
}
};
/**
* Checks if obj is an object in the WebDriverError prototypal chain.