Bug 1107706: Part 6: Make SpecialPowersError a prototypal Error

If special powers is imported using Components.utils.import on B2G which
has some special concepts around global scoping, a TypeError will be
raised unless the custom error is a prototypal Error.

An explanation can be found for a similar issue in bug 843892, which
states that toString is attached to the instances rather than the
prototype, and that this causes problems once the object goes through
Object.freeze.  It was patched in bug 1014484.

This patch also renames SpecialPowersException to SpecialPowersError.
This commit is contained in:
Andreas Tolfsen 2015-02-26 17:40:21 +00:00
parent fe54ac0fd1
commit 8b1e3107f2

View File

@ -1,6 +1,7 @@
/* 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";
Components.utils.import("resource://gre/modules/Services.jsm");
@ -13,18 +14,16 @@ if (typeof(Cc) == 'undefined') {
var Cc = Components.classes;
}
/**
* Special Powers Exception - used to throw exceptions nicely
**/
this.SpecialPowersException = function SpecialPowersException(aMsg) {
this.SpecialPowersError = function(aMsg) {
Error.call(this);
let {stack} = new Error();
this.message = aMsg;
this.name = "SpecialPowersException";
this.name = "SpecialPowersError";
}
SpecialPowersError.prototype = Object.create(Error.prototype);
SpecialPowersException.prototype = {
toString: function SPE_toString() {
return this.name + ': "' + this.message + '"';
}
SpecialPowersError.prototype.toString = function() {
return `${this.name}: ${this.message}`;
};
this.SpecialPowersObserverAPI = function SpecialPowersObserverAPI() {
@ -221,7 +220,7 @@ SpecialPowersObserverAPI.prototype = {
}
if (status == 404) {
throw new SpecialPowersException(
throw new SpecialPowersError(
"Error while executing chrome script '" + aUrl + "':\n" +
"The script doesn't exists. Ensure you have registered it in " +
"'support-files' in your mochitest.ini.");
@ -247,19 +246,19 @@ SpecialPowersObserverAPI.prototype = {
if (aMessage.json.op == "get") {
if (!prefName || !prefType)
throw new SpecialPowersException("Invalid parameters for get in SPPrefService");
throw new SpecialPowersError("Invalid parameters for get in SPPrefService");
// return null if the pref doesn't exist
if (prefs.getPrefType(prefName) == prefs.PREF_INVALID)
return null;
} else if (aMessage.json.op == "set") {
if (!prefName || !prefType || prefValue === null)
throw new SpecialPowersException("Invalid parameters for set in SPPrefService");
throw new SpecialPowersError("Invalid parameters for set in SPPrefService");
} else if (aMessage.json.op == "clear") {
if (!prefName)
throw new SpecialPowersException("Invalid parameters for clear in SPPrefService");
throw new SpecialPowersError("Invalid parameters for clear in SPPrefService");
} else {
throw new SpecialPowersException("Invalid operation for SPPrefService");
throw new SpecialPowersError("Invalid operation for SPPrefService");
}
// Now we make the call
@ -306,7 +305,7 @@ SpecialPowersObserverAPI.prototype = {
case "find-crash-dump-files":
return this._findCrashDumpFiles(aMessage.json.crashDumpFilesToIgnore);
default:
throw new SpecialPowersException("Invalid operation for SPProcessCrashService");
throw new SpecialPowersError("Invalid operation for SPProcessCrashService");
}
return undefined; // See comment at the beginning of this function.
}
@ -338,8 +337,8 @@ SpecialPowersObserverAPI.prototype = {
return false;
break;
default:
throw new SpecialPowersException("Invalid operation for " +
"SPPermissionManager");
throw new SpecialPowersError(
"Invalid operation for SPPermissionManager");
}
return undefined; // See comment at the beginning of this function.
}
@ -377,7 +376,7 @@ SpecialPowersObserverAPI.prototype = {
return;
}
default:
throw new SpecialPowersException("Invalid operation for SPWebAppsService");
throw new SpecialPowersError("Invalid operation for SPWebAppsService");
}
return undefined; // See comment at the beginning of this function.
}
@ -390,7 +389,7 @@ SpecialPowersObserverAPI.prototype = {
Services.obs.notifyObservers(null, topic, data);
break;
default:
throw new SpecialPowersException("Invalid operation for SPObserverervice");
throw new SpecialPowersError("Invalid operation for SPObserverervice");
}
return undefined; // See comment at the beginning of this function.
}
@ -443,9 +442,10 @@ SpecialPowersObserverAPI.prototype = {
try {
Components.utils.evalInSandbox(jsScript, sb, "1.8", url, 1);
} catch(e) {
throw new SpecialPowersException("Error while executing chrome " +
"script '" + url + "':\n" + e + "\n" +
e.fileName + ":" + e.lineNumber);
throw new SpecialPowersError(
"Error while executing chrome script '" + url + "':\n" +
e + "\n" +
e.fileName + ":" + e.lineNumber);
}
return undefined; // See comment at the beginning of this function.
}
@ -471,7 +471,7 @@ SpecialPowersObserverAPI.prototype = {
let op = msg.op;
if (op != 'clear' && op != 'getUsage') {
throw new SpecialPowersException('Invalid operation for SPQuotaManager');
throw new SpecialPowersError('Invalid operation for SPQuotaManager');
}
let uri = this._getURI(msg.uri);
@ -510,13 +510,12 @@ SpecialPowersObserverAPI.prototype = {
}
default:
throw new SpecialPowersException("Unrecognized Special Powers API");
throw new SpecialPowersError("Unrecognized Special Powers API");
}
// We throw an exception before reaching this explicit return because
// we should never be arriving here anyway.
throw new SpecialPowersException("Unreached code");
throw new SpecialPowersError("Unreached code");
return undefined;
}
};