From e9ea0a6288ad8ac3d2944feacad0dfacf5c7ed39 Mon Sep 17 00:00:00 2001 From: shreyas Date: Mon, 23 Feb 2015 18:45:00 -0800 Subject: [PATCH] Bug 394686 - passwordmgr: Throw Components.Exceptions and Error instead of strings. r=MattN --- .../components/passwordmgr/LoginHelper.jsm | 28 +++++++-------- .../passwordmgr/LoginManagerContent.jsm | 4 +-- .../components/passwordmgr/nsLoginManager.js | 22 ++++++------ .../passwordmgr/nsLoginManagerPrompter.js | 34 +++++++++---------- .../components/passwordmgr/storage-json.js | 14 ++++---- .../passwordmgr/storage-mozStorage.js | 26 +++++++------- .../passwordmgr/test/auth2/authenticate.sjs | 8 ++--- .../passwordmgr/test/authenticate.sjs | 8 ++--- .../passwordmgr/test/browser/authenticate.sjs | 4 +-- .../test/unit/test_notifications.js | 2 +- .../test/unit/test_storage_mozStorage.js | 2 +- 11 files changed, 75 insertions(+), 77 deletions(-) diff --git a/toolkit/components/passwordmgr/LoginHelper.jsm b/toolkit/components/passwordmgr/LoginHelper.jsm index 9f9d74b8342..86c4e0dd566 100644 --- a/toolkit/components/passwordmgr/LoginHelper.jsm +++ b/toolkit/components/passwordmgr/LoginHelper.jsm @@ -48,7 +48,7 @@ this.LoginHelper = { aHostname.indexOf("\r") != -1 || aHostname.indexOf("\n") != -1 || aHostname.indexOf("\0") != -1) { - throw "Invalid hostname"; + throw new Error("Invalid hostname"); } }, @@ -73,7 +73,7 @@ this.LoginHelper = { // Nulls are invalid, as they don't round-trip well. // Mostly not a formatting problem, although ".\0" can be quirky. if (badCharacterPresent(aLogin, "\0")) { - throw "login values can't contain nulls"; + throw new Error("login values can't contain nulls"); } // In theory these nulls should just be rolled up into the encrypted @@ -82,26 +82,26 @@ this.LoginHelper = { // unexpected round-trip surprises. if (aLogin.username.indexOf("\0") != -1 || aLogin.password.indexOf("\0") != -1) { - throw "login values can't contain nulls"; + throw new Error("login values can't contain nulls"); } // Newlines are invalid for any field stored as plaintext. if (badCharacterPresent(aLogin, "\r") || badCharacterPresent(aLogin, "\n")) { - throw "login values can't contain newlines"; + throw new Error("login values can't contain newlines"); } // A line with just a "." can have special meaning. if (aLogin.usernameField == "." || aLogin.formSubmitURL == ".") { - throw "login values can't be periods"; + throw new Error("login values can't be periods"); } // A hostname with "\ \(" won't roundtrip. // eg host="foo (", realm="bar" --> "foo ( (bar)" // vs host="foo", realm=" (bar" --> "foo ( (bar)" if (aLogin.hostname.indexOf(" (") != -1) { - throw "bad parens in hostname"; + throw new Error("bad parens in hostname"); } }, @@ -189,40 +189,40 @@ this.LoginHelper = { // Fail if caller requests setting an unknown property. default: - throw "Unexpected propertybag item: " + prop.name; + throw new Error("Unexpected propertybag item: " + prop.name); } } } else { - throw "newLoginData needs an expected interface!"; + throw new Error("newLoginData needs an expected interface!"); } // Sanity check the login if (newLogin.hostname == null || newLogin.hostname.length == 0) { - throw "Can't add a login with a null or empty hostname."; + throw new Error("Can't add a login with a null or empty hostname."); } // For logins w/o a username, set to "", not null. if (newLogin.username == null) { - throw "Can't add a login with a null username."; + throw new Error("Can't add a login with a null username."); } if (newLogin.password == null || newLogin.password.length == 0) { - throw "Can't add a login with a null or empty password."; + throw new Error("Can't add a login with a null or empty password."); } if (newLogin.formSubmitURL || newLogin.formSubmitURL == "") { // We have a form submit URL. Can't have a HTTP realm. if (newLogin.httpRealm != null) { - throw "Can't add a login with both a httpRealm and formSubmitURL."; + throw new Error("Can't add a login with both a httpRealm and formSubmitURL."); } } else if (newLogin.httpRealm) { // We have a HTTP realm. Can't have a form submit URL. if (newLogin.formSubmitURL != null) { - throw "Can't add a login with both a httpRealm and formSubmitURL."; + throw new Error("Can't add a login with both a httpRealm and formSubmitURL."); } } else { // Need one or the other! - throw "Can't add a login without a httpRealm or formSubmitURL."; + throw new Error(Can't add a login without a httpRealm or formSubmitURL."); } // Throws if there are bogus values. diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm index e190fd3dfc6..abcf3eb07f0 100644 --- a/toolkit/components/passwordmgr/LoginManagerContent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm @@ -955,7 +955,7 @@ UserAutoCompleteResult.prototype = { getValueAt : function (index) { if (index < 0 || index >= this.logins.length) - throw "Index out of range."; + throw new Error("Index out of range."); return this.logins[index].username; }, @@ -982,7 +982,7 @@ UserAutoCompleteResult.prototype = { removeValueAt : function (index, removeFromDB) { if (index < 0 || index >= this.logins.length) - throw "Index out of range."; + throw new Error("Index out of range."); var [removedLogin] = this.logins.splice(index, 1); diff --git a/toolkit/components/passwordmgr/nsLoginManager.js b/toolkit/components/passwordmgr/nsLoginManager.js index 19f2d8041f3..332dbd17f2a 100644 --- a/toolkit/components/passwordmgr/nsLoginManager.js +++ b/toolkit/components/passwordmgr/nsLoginManager.js @@ -3,9 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; +const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); @@ -74,7 +72,7 @@ LoginManager.prototype = { return this; } - throw Cr.NS_ERROR_NO_INTERFACE; + throw new Components.Exception("Interface not available", Cr.NS_ERROR_NO_INTERFACE); }, @@ -301,26 +299,26 @@ LoginManager.prototype = { addLogin : function (login) { // Sanity check the login if (login.hostname == null || login.hostname.length == 0) - throw "Can't add a login with a null or empty hostname."; + throw new Error("Can't add a login with a null or empty hostname."); // For logins w/o a username, set to "", not null. if (login.username == null) - throw "Can't add a login with a null username."; + throw new Error("Can't add a login with a null username."); if (login.password == null || login.password.length == 0) - throw "Can't add a login with a null or empty password."; + throw new Error("Can't add a login with a null or empty password."); if (login.formSubmitURL || login.formSubmitURL == "") { // We have a form submit URL. Can't have a HTTP realm. if (login.httpRealm != null) - throw "Can't add a login with both a httpRealm and formSubmitURL."; + throw new Error("Can't add a login with both a httpRealm and formSubmitURL."); } else if (login.httpRealm) { // We have a HTTP realm. Can't have a form submit URL. if (login.formSubmitURL != null) - throw "Can't add a login with both a httpRealm and formSubmitURL."; + throw new Error("Can't add a login with both a httpRealm and formSubmitURL."); } else { // Need one or the other! - throw "Can't add a login without a httpRealm or formSubmitURL."; + throw new Error("Can't add a login without a httpRealm or formSubmitURL."); } @@ -329,7 +327,7 @@ LoginManager.prototype = { login.httpRealm); if (logins.some(function(l) login.matches(l, true))) - throw "This login already exists."; + throw new Error("This login already exists."); log("Adding login"); return this._storage.addLogin(login); @@ -480,7 +478,7 @@ LoginManager.prototype = { setLoginSavingEnabled : function (hostname, enabled) { // Nulls won't round-trip with getAllDisabledHosts(). if (hostname.indexOf("\0") != -1) - throw "Invalid hostname"; + throw new Error("Invalid hostname"); log("Login saving for", hostname, "now enabled?", enabled); return this._storage.setLoginSavingEnabled(hostname, enabled); diff --git a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js index 1a837e935aa..d5fc25e7b4f 100644 --- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js +++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js @@ -3,15 +3,12 @@ * 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/. */ +const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); -Components.utils.import("resource://gre/modules/SharedPromptUtils.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); +Cu.import("resource://gre/modules/SharedPromptUtils.jsm"); /* * LoginManagerPromptFactory @@ -126,7 +123,7 @@ LoginManagerPromptFactory.prototype = { } self._doAsyncPrompt(); } - } + }; Services.tm.mainThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL); this.log("_doAsyncPrompt:run dispatched"); @@ -231,7 +228,7 @@ LoginManagerPrompter.prototype = { this.__strBundle = bunService.createBundle( "chrome://passwordmgr/locale/passwordmgr.properties"); if (!this.__strBundle) - throw "String bundle for Login Manager not present!"; + throw new Error("String bundle for Login Manager not present!"); } return this.__strBundle; @@ -294,7 +291,8 @@ LoginManagerPrompter.prototype = { prompt : function (aDialogTitle, aText, aPasswordRealm, aSavePassword, aDefaultText, aResult) { if (aSavePassword != Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER) - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + throw new Components.Exception("prompt only supports SAVE_PASSWORD_NEVER", + Cr.NS_ERROR_NOT_IMPLEMENTED); this.log("===== prompt() called ====="); @@ -318,7 +316,8 @@ LoginManagerPrompter.prototype = { this.log("===== promptUsernameAndPassword() called ====="); if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION) - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + throw new Components.Exception("promptUsernameAndPassword doesn't support SAVE_PASSWORD_FOR_SESSION", + Cr.NS_ERROR_NOT_IMPLEMENTED); var selectedLogin = null; var checkBox = { value : false }; @@ -420,7 +419,8 @@ LoginManagerPrompter.prototype = { this.log("===== promptPassword called() ====="); if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION) - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + throw new Components.Exception("promptPassword doesn't support SAVE_PASSWORD_FOR_SESSION", + Cr.NS_ERROR_NOT_IMPLEMENTED); var checkBox = { value : false }; var checkBoxLabel = null; @@ -679,7 +679,7 @@ LoginManagerPrompter.prototype = { level: aLevel, inProgress : false, prompter: this - } + }; this._factory._asyncPrompts[hashKey] = asyncPrompt; this._factory._doAsyncPrompt(); @@ -1433,11 +1433,11 @@ LoginManagerPrompter.prototype = { if (aAuthInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) { this.log("getAuthTarget is for proxy auth"); if (!(aChannel instanceof Ci.nsIProxiedChannel)) - throw "proxy auth needs nsIProxiedChannel"; + throw new Error("proxy auth needs nsIProxiedChannel"); var info = aChannel.proxyInfo; if (!info) - throw "proxy auth needs nsIProxyInfo"; + throw new Error("proxy auth needs nsIProxyInfo"); // Proxies don't have a scheme, but we'll use "moz-proxy://" // so that it's more obvious what the login is for. @@ -1520,7 +1520,7 @@ LoginManagerPrompter.prototype = { this.callback = null; this.context = null; } - } + }; } }; // end of LoginManagerPrompter implementation diff --git a/toolkit/components/passwordmgr/storage-json.js b/toolkit/components/passwordmgr/storage-json.js index fed1f0616ea..253e4f5a2b2 100644 --- a/toolkit/components/passwordmgr/storage-json.js +++ b/toolkit/components/passwordmgr/storage-json.js @@ -115,7 +115,7 @@ this.LoginManagerStorage_json.prototype = { }.bind(this)).catch(Cu.reportError); } catch (e) { this.log("Initialization failed: " + e); - throw "Initialization failed"; + throw new Error("Initialization failed"); } }, @@ -151,7 +151,7 @@ this.LoginManagerStorage_json.prototype = { loginClone.QueryInterface(Ci.nsILoginMetaInfo); if (loginClone.guid) { if (!this._isGuidUnique(loginClone.guid)) - throw "specified GUID already exists"; + throw new Error("specified GUID already exists"); } else { loginClone.guid = gUUIDGenerator.generateUUID().toString(); } @@ -199,7 +199,7 @@ this.LoginManagerStorage_json.prototype = { let [idToDelete, storedLogin] = this._getIdForLogin(login); if (!idToDelete) - throw "No matching logins"; + throw new Error("No matching logins"); let foundIndex = this._store.data.logins.findIndex(l => l.id == idToDelete); if (foundIndex != -1) { @@ -220,7 +220,7 @@ this.LoginManagerStorage_json.prototype = { let [idToModify, oldStoredLogin] = this._getIdForLogin(oldLogin); if (!idToModify) - throw "No matching logins"; + throw new Error("No matching logins"); let newLogin = LoginHelper.buildModifiedLogin(oldStoredLogin, newLoginData); @@ -228,7 +228,7 @@ this.LoginManagerStorage_json.prototype = { if (newLogin.guid != oldStoredLogin.guid && !this._isGuidUnique(newLogin.guid)) { - throw "specified GUID already exists"; + throw new Error("specified GUID already exists"); } // Look for an existing entry in case key properties changed. @@ -238,7 +238,7 @@ this.LoginManagerStorage_json.prototype = { newLogin.httpRealm); if (logins.some(login => newLogin.matches(login, true))) - throw "This login already exists."; + throw new Error("This login already exists."); } // Get the encrypted value of the username and password. @@ -362,7 +362,7 @@ this.LoginManagerStorage_json.prototype = { break; // Fail if caller requests an unknown property. default: - throw "Unexpected field: " + field; + throw new Error("Unexpected field: " + field); } } return true; diff --git a/toolkit/components/passwordmgr/storage-mozStorage.js b/toolkit/components/passwordmgr/storage-mozStorage.js index 14ac727129f..b415437d1dd 100644 --- a/toolkit/components/passwordmgr/storage-mozStorage.js +++ b/toolkit/components/passwordmgr/storage-mozStorage.js @@ -66,7 +66,7 @@ LoginManagerStorage_mozStorage.prototype = { return this._dbConnection; } - throw Cr.NS_ERROR_NO_INTERFACE; + throw new Components.Exception("Interface not available", Cr.NS_ERROR_NO_INTERFACE); }, __crypto : null, // nsILoginManagerCrypto service @@ -220,7 +220,7 @@ LoginManagerStorage_mozStorage.prototype = { // If the import fails on first run, we want to delete the db if (isFirstRun && e == "Import failed") this._dbCleanup(false); - throw "Initialization failed"; + throw new Error("Initialization failed"); } }, @@ -253,7 +253,7 @@ LoginManagerStorage_mozStorage.prototype = { loginClone.QueryInterface(Ci.nsILoginMetaInfo); if (loginClone.guid) { if (!this._isGuidUnique(loginClone.guid)) - throw "specified GUID already exists"; + throw new Error("specified GUID already exists"); } else { loginClone.guid = this._uuidService.generateUUID().toString(); } @@ -302,7 +302,7 @@ LoginManagerStorage_mozStorage.prototype = { stmt.execute(); } catch (e) { this.log("addLogin failed: " + e.name + " : " + e.message); - throw "Couldn't write to database, login not added."; + throw new Error("Couldn't write to database, login not added."); } finally { if (stmt) { stmt.reset(); @@ -321,7 +321,7 @@ LoginManagerStorage_mozStorage.prototype = { removeLogin : function (login) { let [idToDelete, storedLogin] = this._getIdForLogin(login); if (!idToDelete) - throw "No matching logins"; + throw new Error("No matching logins"); // Execute the statement & remove from DB let query = "DELETE FROM moz_logins WHERE id = :id"; @@ -335,7 +335,7 @@ LoginManagerStorage_mozStorage.prototype = { transaction.commit(); } catch (e) { this.log("_removeLogin failed: " + e.name + " : " + e.message); - throw "Couldn't write to database, login not removed."; + throw new Error("Couldn't write to database, login not removed."); transaction.rollback(); } finally { if (stmt) { @@ -353,7 +353,7 @@ LoginManagerStorage_mozStorage.prototype = { modifyLogin : function (oldLogin, newLoginData) { let [idToModify, oldStoredLogin] = this._getIdForLogin(oldLogin); if (!idToModify) - throw "No matching logins"; + throw new Error("No matching logins"); let newLogin = LoginHelper.buildModifiedLogin(oldStoredLogin, newLoginData); @@ -361,7 +361,7 @@ LoginManagerStorage_mozStorage.prototype = { if (newLogin.guid != oldStoredLogin.guid && !this._isGuidUnique(newLogin.guid)) { - throw "specified GUID already exists"; + throw new Error("specified GUID already exists"); } // Look for an existing entry in case key properties changed. @@ -371,7 +371,7 @@ LoginManagerStorage_mozStorage.prototype = { newLogin.httpRealm); if (logins.some(login => newLogin.matches(login, true))) - throw "This login already exists."; + throw new Error("This login already exists."); } // Get the encrypted value of the username and password. @@ -417,7 +417,7 @@ LoginManagerStorage_mozStorage.prototype = { stmt.execute(); } catch (e) { this.log("modifyLogin failed: " + e.name + " : " + e.message); - throw "Couldn't write to database, login not modified."; + throw new Error("Couldn't write to database, login not modified."); } finally { if (stmt) { stmt.reset(); @@ -519,7 +519,7 @@ LoginManagerStorage_mozStorage.prototype = { break; // Fail if caller requests an unknown property. default: - throw "Unexpected field: " + field; + throw new Error("Unexpected field: " + field); } } @@ -610,7 +610,7 @@ LoginManagerStorage_mozStorage.prototype = { } catch (e) { this.log("_removeAllLogins failed: " + e.name + " : " + e.message); transaction.rollback(); - throw "Couldn't write to database"; + throw new Error("Couldn't write to database"); } finally { if (stmt) { stmt.reset(); @@ -669,7 +669,7 @@ LoginManagerStorage_mozStorage.prototype = { stmt.execute(); } catch (e) { this.log("setLoginSavingEnabled failed: " + e.name + " : " + e.message); - throw "Couldn't write to database" + throw new Error("Couldn't write to database"); } finally { if (stmt) { stmt.reset(); diff --git a/toolkit/components/passwordmgr/test/auth2/authenticate.sjs b/toolkit/components/passwordmgr/test/auth2/authenticate.sjs index 58da655cf98..d2f65001316 100644 --- a/toolkit/components/passwordmgr/test/auth2/authenticate.sjs +++ b/toolkit/components/passwordmgr/test/auth2/authenticate.sjs @@ -86,12 +86,12 @@ function reallyHandleRequest(request, response) { authHeader = request.getHeader("Authorization"); match = /Basic (.+)/.exec(authHeader); if (match.length != 2) - throw "Couldn't parse auth header: " + authHeader; + throw new Error("Couldn't parse auth header: " + authHeader); var userpass = base64ToString(match[1]); // no atob() :-( match = /(.*):(.*)/.exec(userpass); if (match.length != 3) - throw "Couldn't decode auth header: " + userpass; + throw new Error("Couldn't decode auth header: " + userpass); actual_user = match[1]; actual_pass = match[2]; } @@ -101,12 +101,12 @@ function reallyHandleRequest(request, response) { authHeader = request.getHeader("Proxy-Authorization"); match = /Basic (.+)/.exec(authHeader); if (match.length != 2) - throw "Couldn't parse auth header: " + authHeader; + throw new Error("Couldn't parse auth header: " + authHeader); var userpass = base64ToString(match[1]); // no atob() :-( match = /(.*):(.*)/.exec(userpass); if (match.length != 3) - throw "Couldn't decode auth header: " + userpass; + throw new Error("Couldn't decode auth header: " + userpass); proxy_actual_user = match[1]; proxy_actual_pass = match[2]; } diff --git a/toolkit/components/passwordmgr/test/authenticate.sjs b/toolkit/components/passwordmgr/test/authenticate.sjs index 92947ec0c9d..42edc32203c 100644 --- a/toolkit/components/passwordmgr/test/authenticate.sjs +++ b/toolkit/components/passwordmgr/test/authenticate.sjs @@ -91,12 +91,12 @@ function reallyHandleRequest(request, response) { authHeader = request.getHeader("Authorization"); match = /Basic (.+)/.exec(authHeader); if (match.length != 2) - throw "Couldn't parse auth header: " + authHeader; + throw new Error("Couldn't parse auth header: " + authHeader); var userpass = base64ToString(match[1]); // no atob() :-( match = /(.*):(.*)/.exec(userpass); if (match.length != 3) - throw "Couldn't decode auth header: " + userpass; + throw new Error("Couldn't decode auth header: " + userpass); actual_user = match[1]; actual_pass = match[2]; } @@ -106,12 +106,12 @@ function reallyHandleRequest(request, response) { authHeader = request.getHeader("Proxy-Authorization"); match = /Basic (.+)/.exec(authHeader); if (match.length != 2) - throw "Couldn't parse auth header: " + authHeader; + throw new Error("Couldn't parse auth header: " + authHeader); var userpass = base64ToString(match[1]); // no atob() :-( match = /(.*):(.*)/.exec(userpass); if (match.length != 3) - throw "Couldn't decode auth header: " + userpass; + throw new Error("Couldn't decode auth header: " + userpass); proxy_actual_user = match[1]; proxy_actual_pass = match[2]; } diff --git a/toolkit/components/passwordmgr/test/browser/authenticate.sjs b/toolkit/components/passwordmgr/test/browser/authenticate.sjs index 7e4cf3c0252..fe2d2423cbb 100644 --- a/toolkit/components/passwordmgr/test/browser/authenticate.sjs +++ b/toolkit/components/passwordmgr/test/browser/authenticate.sjs @@ -24,12 +24,12 @@ function handleRequest(request, response) authHeader = request.getHeader("Authorization"); match = /Basic (.+)/.exec(authHeader); if (match.length != 2) - throw "Couldn't parse auth header: " + authHeader; + throw new Error("Couldn't parse auth header: " + authHeader); var userpass = base64ToString(match[1]); // no atob() :-( match = /(.*):(.*)/.exec(userpass); if (match.length != 3) - throw "Couldn't decode auth header: " + userpass; + throw new Error("Couldn't decode auth header: " + userpass); actual_user = match[1]; actual_pass = match[2]; } diff --git a/toolkit/components/passwordmgr/test/unit/test_notifications.js b/toolkit/components/passwordmgr/test/unit/test_notifications.js index ded39f03282..df160aa6ae3 100644 --- a/toolkit/components/passwordmgr/test/unit/test_notifications.js +++ b/toolkit/components/passwordmgr/test/unit/test_notifications.js @@ -166,7 +166,7 @@ Services.obs.removeObserver(TestObserver, "passwordmgr-storage-changed"); LoginTest.clearData(); } catch (e) { - throw "FAILED in test #" + testnum + " -- " + testdesc + ": " + e; + throw new Error("FAILED in test #" + testnum + " -- " + testdesc + ": " + e); } }); diff --git a/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js b/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js index a297c601b3f..25c048f38dd 100644 --- a/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js +++ b/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js @@ -423,7 +423,7 @@ LoginTest.deleteFile(OS.Constants.Path.profileDir, filename + ".corrupt"); LoginTest.deleteFile(OS.Constants.Path.profileDir, filename); } catch (e) { - throw "FAILED in test #" + testnum + " -- " + testdesc + ": " + e; + throw new Error("FAILED in test #" + testnum + " -- " + testdesc + ": " + e); } });