Better handle some file sync file access errors
- Catch additional errors on Windows (too-long paths, maybe aliases) - Fix "Show File" button (which didn't show in some cases, at least on Windows) - Clarify error message
This commit is contained in:
parent
e716a5367a
commit
2236bab130
5 changed files with 85 additions and 95 deletions
|
@ -523,54 +523,34 @@ Zotero.File = new function(){
|
|||
}
|
||||
|
||||
if (e.name == 'NS_ERROR_FILE_ACCESS_DENIED' || e.name == 'NS_ERROR_FILE_IS_LOCKED'
|
||||
// Shows up on some Windows systems
|
||||
|| e.name == 'NS_ERROR_FAILURE') {
|
||||
// These show up on some Windows systems
|
||||
|| e.name == 'NS_ERROR_FAILURE' || e.name == 'NS_ERROR_FILE_NOT_FOUND') {
|
||||
Zotero.debug(e);
|
||||
str = str + " " + Zotero.getString('file.accessError.cannotBe') + " " + opWord + ".";
|
||||
var checkFileWindows = Zotero.getString('file.accessError.message.windows');
|
||||
var checkFileOther = Zotero.getString('file.accessError.message.other');
|
||||
var msg = str + " "
|
||||
var msg = str + "\n\n"
|
||||
+ (Zotero.isWin ? checkFileWindows : checkFileOther)
|
||||
+ "\n\n"
|
||||
+ Zotero.getString('file.accessError.restart');
|
||||
|
||||
if (operation == 'create') {
|
||||
var e = new Zotero.Error(
|
||||
msg,
|
||||
0,
|
||||
{
|
||||
dialogButtonText: Zotero.getString('file.accessError.showParentDir'),
|
||||
dialogButtonCallback: function () {
|
||||
try {
|
||||
file.parent.QueryInterface(Components.interfaces.nsILocalFile).reveal();
|
||||
}
|
||||
// Unsupported on some platforms
|
||||
catch (e2) {
|
||||
Zotero.debug(e2);
|
||||
}
|
||||
var e = new Zotero.Error(
|
||||
msg,
|
||||
0,
|
||||
{
|
||||
dialogButtonText: Zotero.getString('file.accessError.showParentDir'),
|
||||
dialogButtonCallback: function () {
|
||||
try {
|
||||
file.parent.QueryInterface(Components.interfaces.nsILocalFile);
|
||||
file.parent.reveal();
|
||||
}
|
||||
// Unsupported on some platforms
|
||||
catch (e2) {
|
||||
Zotero.launchFile(file.parent);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
var e = new Zotero.Error(
|
||||
msg,
|
||||
0,
|
||||
{
|
||||
dialogButtonText: Zotero.getString('locate.showFile.label'),
|
||||
dialogButtonCallback: function () {
|
||||
try {
|
||||
file.QueryInterface(Components.interfaces.nsILocalFile);
|
||||
file.reveal();
|
||||
}
|
||||
// Unsupported on some platforms
|
||||
catch (e2) {
|
||||
Zotero.debug(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
throw (e);
|
||||
|
|
|
@ -1607,18 +1607,18 @@ Zotero.Sync.Storage = new function () {
|
|||
|
||||
// Do deletes outside of the enumerator to avoid an access error on Windows
|
||||
for each(var file in filesToDelete) {
|
||||
if (file.isFile()) {
|
||||
Zotero.debug("Deleting existing file " + file.leafName);
|
||||
try {
|
||||
try {
|
||||
if (file.isFile()) {
|
||||
Zotero.debug("Deleting existing file " + file.leafName);
|
||||
file.remove(false);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.File.checkFileAccessError(e, file, 'delete');
|
||||
else if (file.isDirectory()) {
|
||||
Zotero.debug("Deleting existing directory " + file.leafName);
|
||||
file.remove(true);
|
||||
}
|
||||
}
|
||||
else if (file.isDirectory()) {
|
||||
Zotero.debug("Deleting existing directory " + file.leafName);
|
||||
file.remove(true);
|
||||
catch (e) {
|
||||
Zotero.File.checkFileAccessError(e, file, 'delete');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1146,6 +1146,58 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Launch a file, the best way we can
|
||||
*/
|
||||
this.launchFile = function (file) {
|
||||
try {
|
||||
file.launch();
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug("launch() not supported -- trying fallback executable");
|
||||
|
||||
try {
|
||||
if (Zotero.isWin) {
|
||||
var pref = "fallbackLauncher.windows";
|
||||
}
|
||||
else {
|
||||
var pref = "fallbackLauncher.unix";
|
||||
}
|
||||
var path = Zotero.Prefs.get(pref);
|
||||
|
||||
var exec = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
exec.initWithPath(path);
|
||||
if (!exec.exists()) {
|
||||
throw (path + " does not exist");
|
||||
}
|
||||
|
||||
var proc = Components.classes["@mozilla.org/process/util;1"]
|
||||
.createInstance(Components.interfaces.nsIProcess);
|
||||
proc.init(exec);
|
||||
|
||||
var args = [file.path];
|
||||
proc.runw(true, args, args.length);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e);
|
||||
Zotero.debug("Launching via executable failed -- passing to loadUrl()");
|
||||
|
||||
// If nsILocalFile.launch() isn't available and the fallback
|
||||
// executable doesn't exist, we just let the Firefox external
|
||||
// helper app window handle it
|
||||
var nsIFPH = Components.classes["@mozilla.org/network/protocol;1?name=file"]
|
||||
.getService(Components.interfaces.nsIFileProtocolHandler);
|
||||
var uri = nsIFPH.newFileURI(file);
|
||||
|
||||
var nsIEPS = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
getService(Components.interfaces.nsIExternalProtocolService);
|
||||
nsIEPS.loadUrl(uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debug logging function
|
||||
*
|
||||
|
@ -1854,6 +1906,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
|||
Zotero.Items.reloadAll();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Brings Zotero Standalone to the foreground
|
||||
*/
|
||||
|
|
|
@ -3464,7 +3464,7 @@ var ZoteroPane = new function()
|
|||
this.loadURI(url, event);
|
||||
}
|
||||
else {
|
||||
this.launchFile(file);
|
||||
Zotero.launchFile(file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -3507,54 +3507,11 @@ var ZoteroPane = new function()
|
|||
|
||||
|
||||
/**
|
||||
* Launch a file, the best way we can
|
||||
* @deprecated
|
||||
*/
|
||||
this.launchFile = function (file) {
|
||||
try {
|
||||
file.launch();
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug("launch() not supported -- trying fallback executable");
|
||||
|
||||
try {
|
||||
if (Zotero.isWin) {
|
||||
var pref = "fallbackLauncher.windows";
|
||||
}
|
||||
else {
|
||||
var pref = "fallbackLauncher.unix";
|
||||
}
|
||||
var path = Zotero.Prefs.get(pref);
|
||||
|
||||
var exec = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
exec.initWithPath(path);
|
||||
if (!exec.exists()) {
|
||||
throw (path + " does not exist");
|
||||
}
|
||||
|
||||
var proc = Components.classes["@mozilla.org/process/util;1"]
|
||||
.createInstance(Components.interfaces.nsIProcess);
|
||||
proc.init(exec);
|
||||
|
||||
var args = [file.path];
|
||||
proc.runw(true, args, args.length);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e);
|
||||
Zotero.debug("Launching via executable failed -- passing to loadUrl()");
|
||||
|
||||
// If nsILocalFile.launch() isn't available and the fallback
|
||||
// executable doesn't exist, we just let the Firefox external
|
||||
// helper app window handle it
|
||||
var nsIFPH = Components.classes["@mozilla.org/network/protocol;1?name=file"]
|
||||
.getService(Components.interfaces.nsIFileProtocolHandler);
|
||||
var uri = nsIFPH.newFileURI(file);
|
||||
|
||||
var nsIEPS = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
getService(Components.interfaces.nsIExternalProtocolService);
|
||||
nsIEPS.loadUrl(uri);
|
||||
}
|
||||
}
|
||||
Zotero.debug("ZoteroPane.launchFile() is deprecated -- use Zotero.launchFile()", 2);
|
||||
Zotero.launchFile(file);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3626,7 +3583,7 @@ var ZoteroPane = new function()
|
|||
// On platforms that don't support nsILocalFile.reveal() (e.g. Linux),
|
||||
// launch the parent directory
|
||||
var parent = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
|
||||
this.launchFile(parent);
|
||||
Zotero.launchFile(parent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -903,7 +903,7 @@ file.accessError.cannotBe = cannot be
|
|||
file.accessError.created = created
|
||||
file.accessError.updated = updated
|
||||
file.accessError.deleted = deleted
|
||||
file.accessError.message.windows = Check that the file is not currently in use and that it is not marked as read-only. To check all files in your Zotero data directory, right-click on the 'zotero' directory, click Properties, clear the Read-Only checkbox, and apply the change to all folders and files in the directory.
|
||||
file.accessError.message.windows = Check that the file is not currently in use, that its permissions allow write access, and that it has a valid filename.
|
||||
file.accessError.message.other = Check that the file is not currently in use and that its permissions allow write access.
|
||||
file.accessError.restart = Restarting your computer or disabling security software may also help.
|
||||
file.accessError.showParentDir = Show Parent Directory
|
||||
|
|
Loading…
Add table
Reference in a new issue