Throw clearer error when 'storage' is a broken symlink
Instead of '(NS_ERROR_FILE_ALREADY_EXISTS) [nsIFile.create]', throw "Broken symlink at <path>". Closes #1834
This commit is contained in:
parent
83cdbd8e5c
commit
8614e73aa8
2 changed files with 74 additions and 7 deletions
|
@ -984,24 +984,59 @@ Zotero.File = new function(){
|
||||||
this.createDirectoryIfMissing = function (dir) {
|
this.createDirectoryIfMissing = function (dir) {
|
||||||
dir = this.pathToFile(dir);
|
dir = this.pathToFile(dir);
|
||||||
if (!dir.exists() || !dir.isDirectory()) {
|
if (!dir.exists() || !dir.isDirectory()) {
|
||||||
if (dir.exists() && !dir.isDirectory()) {
|
if (dir.exists()) {
|
||||||
|
if (!dir.isDirectory()) {
|
||||||
dir.remove(null);
|
dir.remove(null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let isSymlink = false;
|
||||||
|
// isSymlink() fails if the directory doesn't exist, but is true if it's a broken
|
||||||
|
// symlink, in which case exists() returns false
|
||||||
|
try {
|
||||||
|
isSymlink = dir.isSymlink();
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
if (isSymlink) {
|
||||||
|
throw new Error(`Broken symlink at ${dir.path}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0o755);
|
dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0o755);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.createDirectoryIfMissingAsync = function (path) {
|
this.createDirectoryIfMissingAsync = async function (path) {
|
||||||
return Zotero.Promise.resolve(
|
try {
|
||||||
OS.File.makeDir(
|
await OS.File.makeDir(
|
||||||
path,
|
path,
|
||||||
{
|
{
|
||||||
ignoreExisting: true,
|
ignoreExisting: false,
|
||||||
unixMode: 0o755
|
unixMode: 0o755
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
}
|
||||||
|
catch (e) {
|
||||||
|
// If there's a broken symlink at the given path, makeDir() will throw becauseExists,
|
||||||
|
// but exists() will return false
|
||||||
|
if (e.becauseExists) {
|
||||||
|
if (await OS.File.exists(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let isSymlink = false;
|
||||||
|
// Confirm with nsIFile that it's a symlink
|
||||||
|
try {
|
||||||
|
isSymlink = this.pathToFile(path).isSymlink();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
if (isSymlink) {
|
||||||
|
throw new Error(`Broken symlink at ${path}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,38 @@ describe("Zotero.File", function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("#createDirectoryIfMissing()", function () {
|
||||||
|
it("should throw error on broken symlink", async function () {
|
||||||
|
if (Zotero.isWin) {
|
||||||
|
this.skip();
|
||||||
|
};
|
||||||
|
|
||||||
|
var tmpPath = await getTempDirectory();
|
||||||
|
var destPath = OS.Path.join(tmpPath, 'missing');
|
||||||
|
var linkPath = OS.Path.join(tmpPath, 'link');
|
||||||
|
await OS.File.unixSymLink(destPath, linkPath);
|
||||||
|
|
||||||
|
assert.throws(() => Zotero.File.createDirectoryIfMissing(linkPath), /^Broken symlink/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#createDirectoryIfMissingAsync()", function () {
|
||||||
|
it("should throw error on broken symlink", async function () {
|
||||||
|
if (Zotero.isWin) {
|
||||||
|
this.skip();
|
||||||
|
};
|
||||||
|
|
||||||
|
var tmpPath = await getTempDirectory();
|
||||||
|
var destPath = OS.Path.join(tmpPath, 'missing');
|
||||||
|
var linkPath = OS.Path.join(tmpPath, 'link');
|
||||||
|
await OS.File.unixSymLink(destPath, linkPath);
|
||||||
|
|
||||||
|
var e = await getPromiseError(Zotero.File.createDirectoryIfMissingAsync(linkPath));
|
||||||
|
assert.ok(e);
|
||||||
|
assert.match(e.message, /^Broken symlink/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("#zipDirectory()", function () {
|
describe("#zipDirectory()", function () {
|
||||||
it("should compress a directory recursively", function* () {
|
it("should compress a directory recursively", function* () {
|
||||||
var tmpPath = Zotero.getTempDirectory().path;
|
var tmpPath = Zotero.getTempDirectory().path;
|
||||||
|
|
Loading…
Reference in a new issue