From a47c332895519b77164599d39bea14563b764aef Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Tue, 12 Sep 2017 02:35:06 -0400 Subject: [PATCH] Show better error message if data dir can't be created --- chrome/content/zotero/xpcom/dataDirectory.js | 70 +++++++++++++++++++- chrome/content/zotero/xpcom/zotero.js | 6 ++ chrome/locale/en-US/zotero/zotero.properties | 2 + 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/dataDirectory.js b/chrome/content/zotero/xpcom/dataDirectory.js index 960cd62d7c..90649c2dde 100644 --- a/chrome/content/zotero/xpcom/dataDirectory.js +++ b/chrome/content/zotero/xpcom/dataDirectory.js @@ -338,7 +338,75 @@ Zotero.DataDirectory = { } Zotero.debug("Using data directory " + dataDir); - yield Zotero.File.createDirectoryIfMissingAsync(dataDir); + try { + yield Zotero.File.createDirectoryIfMissingAsync(dataDir); + } + catch (e) { + if (e instanceof OS.File.Error + && (('unixErrno' in e && e.unixErrno == OS.Constants.libc.EACCES) + || ('winLastError' in e && e.winLastError == OS.Constants.Win.ERROR_ACCESS_DENIED))) { + Zotero.restarting = true; + let isDefaultDir = dataDir == Zotero.DataDirectory.defaultDir; + let ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] + .createInstance(Components.interfaces.nsIPromptService); + let buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING + + ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING; + if (!isDefaultDir) { + buttonFlags += ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING; + } + let title = Zotero.getString('general.accessDenied'); + let msg = Zotero.getString('dataDir.dirCannotBeCreated', [Zotero.appName, dataDir]) + + "\n\n" + + Zotero.getString('dataDir.checkDirWriteAccess', Zotero.appName); + + let index; + if (isDefaultDir) { + index = ps.confirmEx(null, + title, + msg, + buttonFlags, + Zotero.getString('dataDir.chooseNewDataDirectory'), + Zotero.getString('general.quit'), + null, null, {} + ); + if (index == 0) { + let changed = yield Zotero.DataDirectory.choose(true); + if (!changed) { + Zotero.Utilities.Internal.quit(); + } + } + else if (index == 1) { + Zotero.Utilities.Internal.quit(); + } + } + else { + index = ps.confirmEx(null, + title, + msg, + buttonFlags, + Zotero.getString('dataDir.useDefaultLocation'), + Zotero.getString('general.quit'), + Zotero.getString('dataDir.chooseNewDataDirectory'), + null, {} + ); + if (index == 0) { + Zotero.DataDirectory.set(Zotero.DataDirectory.defaultDir); + Zotero.Utilities.Internal.quit(true); + } + else if (index == 1) { + Zotero.Utilities.Internal.quit(); + } + else if (index == 2) { + let changed = yield Zotero.DataDirectory.choose(true); + if (!changed) { + Zotero.Utilities.Internal.quit(); + return; + } + } + } + return; + } + } this._cache(dataDir); }), diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 73876628fa..7057ddcb21 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -29,6 +29,9 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); Components.utils.import("resource://gre/modules/osfile.jsm"); Components.utils.import("resource://gre/modules/PluralForm.jsm"); +Components.classes["@mozilla.org/net/osfileconstantsservice;1"] + .getService(Components.interfaces.nsIOSFileConstantsService) + .init(); Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); @@ -288,6 +291,9 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js"); try { yield Zotero.DataDirectory.init(); + if (this.restarting) { + return; + } var dataDir = Zotero.DataDirectory.dir; } catch (e) { diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties index 06cbdead19..2add7ff116 100644 --- a/chrome/locale/en-US/zotero/zotero.properties +++ b/chrome/locale/en-US/zotero/zotero.properties @@ -119,6 +119,8 @@ attachmentBasePath.clearBasePath.existingAttachments.singular = One existing at attachmentBasePath.clearBasePath.existingAttachments.plural = %S existing attachments within the old base directory will be converted to use absolute paths. attachmentBasePath.clearBasePath.button = Clear Base Directory Setting +dataDir.dirCannotBeCreated = The %S data directory (%S) cannot be created. +dataDir.checkDirWriteAccess = Make sure you have write access to this directory and that security software isn’t preventing %S from writing to the disk. dataDir.databaseCannotBeOpened = The %S database cannot be opened. dataDir.checkPermissions = Make sure you have read and write permissions for all files in the %1$S data directory and that security software isn’t preventing %1$S from accessing that directory. dataDir.moveToDefaultLocation = You may be able to fix this problem by moving the data directory to the new default location in your home directory. %S will automatically detect the new location.