mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1772726 - Port osfile.jsm usage to IOUtils in services/sync r=markh
Differential Revision: https://phabricator.services.mozilla.com/D148444
This commit is contained in:
parent
3f144b8c3d
commit
ec47642ebf
@ -42,14 +42,9 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
});
|
||||
|
||||
function ensureDirectory(path) {
|
||||
let basename = lazy.OS.Path.dirname(path);
|
||||
return lazy.OS.File.makeDir(basename, {
|
||||
from: lazy.OS.Constants.Path.profileDir,
|
||||
return IOUtils.makeDirectory(PathUtils.parent(path), {
|
||||
createAncestors: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
Observers: "resource://services-common/observers.js",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
Resource: "resource://services-sync/resource.js",
|
||||
});
|
||||
|
||||
@ -725,13 +724,13 @@ BookmarksStore.prototype = {
|
||||
},
|
||||
|
||||
async _openMirror() {
|
||||
let mirrorPath = lazy.OS.Path.join(
|
||||
lazy.OS.Constants.Path.profileDir,
|
||||
let mirrorPath = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
"bookmarks.sqlite"
|
||||
);
|
||||
await lazy.OS.File.makeDir(lazy.OS.Path.dirname(mirrorPath), {
|
||||
from: lazy.OS.Constants.Path.profileDir,
|
||||
await IOUtils.makeDirectory(PathUtils.parent(mirrorPath), {
|
||||
createAncestors: true,
|
||||
});
|
||||
|
||||
return lazy.SyncedBookmarksMirror.open({
|
||||
|
@ -33,7 +33,6 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
FxAccounts: "resource://gre/modules/FxAccounts.jsm",
|
||||
ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
|
||||
Observers: "resource://services-common/observers.js",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
Resource: "resource://services-sync/resource.js",
|
||||
Status: "resource://services-sync/status.js",
|
||||
Svc: "resource://services-sync/util.js",
|
||||
@ -198,23 +197,36 @@ class ErrorSanitizer {
|
||||
"28": this.E_NO_SPACE_ON_DEVICE, // ENOSPC
|
||||
};
|
||||
|
||||
static DOMErrorSubstitutions = {
|
||||
NotFoundError: this.E_NO_FILE_OR_DIR,
|
||||
NotAllowedError: this.E_PERMISSION_DENIED,
|
||||
};
|
||||
|
||||
static reWinError = /^(?<head>Win error (?<errno>\d+))(?<detail>.*) \(.*\r?\n?\)$/m;
|
||||
static reUnixError = /^(?<head>Unix error (?<errno>\d+))(?<detail>.*) \(.*\)$/;
|
||||
|
||||
static #cleanOSErrorMessage(error) {
|
||||
let match = this.reWinError.exec(error);
|
||||
static #cleanOSErrorMessage(message, error = undefined) {
|
||||
if (DOMException.isInstance(error)) {
|
||||
const sub = this.DOMErrorSubstitutions[error.name];
|
||||
message = message.replaceAll("\\", "/");
|
||||
if (sub) {
|
||||
return `${sub} ${message}`;
|
||||
}
|
||||
}
|
||||
|
||||
let match = this.reWinError.exec(message);
|
||||
if (match) {
|
||||
let head =
|
||||
this.WindowsErrorSubstitutions[match.groups.errno] || match.groups.head;
|
||||
return head + match.groups.detail.replaceAll("\\", "/");
|
||||
}
|
||||
match = this.reUnixError.exec(error);
|
||||
match = this.reUnixError.exec(message);
|
||||
if (match) {
|
||||
let head =
|
||||
this.UnixErrorSubstitutions[match.groups.errno] || match.groups.head;
|
||||
return head + match.groups.detail;
|
||||
}
|
||||
return error;
|
||||
return message;
|
||||
}
|
||||
|
||||
// A regex we can use to replace the profile dir in error messages. We use a
|
||||
@ -222,30 +234,36 @@ class ErrorSanitizer {
|
||||
// This escaping function is from:
|
||||
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
|
||||
static reProfileDir = new RegExp(
|
||||
lazy.OS.Constants.Path.profileDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
|
||||
PathUtils.profileDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
|
||||
"gi"
|
||||
);
|
||||
|
||||
// The "public" entry-point.
|
||||
static cleanErrorMessage(error) {
|
||||
/**
|
||||
* Clean an error message, removing PII and normalizing OS-specific messages.
|
||||
*
|
||||
* @param {string} message The error message
|
||||
* @param {Error?} error The error class instance, if any.
|
||||
*/
|
||||
static cleanErrorMessage(message, error = undefined) {
|
||||
// There's a chance the profiledir is in the error string which is PII we
|
||||
// want to avoid including in the ping.
|
||||
error = error.replace(this.reProfileDir, "[profileDir]");
|
||||
message = message.replace(this.reProfileDir, "[profileDir]");
|
||||
// MSG_INVALID_URL from /dom/bindings/Errors.msg -- no way to access this
|
||||
// directly from JS.
|
||||
if (error.endsWith("is not a valid URL.")) {
|
||||
error = "<URL> is not a valid URL.";
|
||||
if (message.endsWith("is not a valid URL.")) {
|
||||
message = "<URL> is not a valid URL.";
|
||||
}
|
||||
// Try to filter things that look somewhat like a URL (in that they contain a
|
||||
// colon in the middle of non-whitespace), in case anything else is including
|
||||
// these in error messages. Note that JSON.stringified stuff comes through
|
||||
// here, so we explicitly ignore double-quotes as well.
|
||||
error = error.replace(/[^\s"]+:[^\s"]+/g, "<URL>");
|
||||
message = message.replace(/[^\s"]+:[^\s"]+/g, "<URL>");
|
||||
|
||||
// Anywhere that's normalized the guid in errors we can easily filter
|
||||
// to make it easier to aggregate these types of errors
|
||||
error = error.replace(/<guid: ([^>]+)>/g, "<GUID>");
|
||||
return this.#cleanOSErrorMessage(error);
|
||||
message = message.replace(/<guid: ([^>]+)>/g, "<GUID>");
|
||||
|
||||
return this.#cleanOSErrorMessage(message, error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1161,6 +1179,13 @@ class SyncTelemetryImpl {
|
||||
return { name: "autherror", from: error.source };
|
||||
}
|
||||
|
||||
if (DOMException.isInstance(error)) {
|
||||
return {
|
||||
name: "unexpectederror",
|
||||
error: ErrorSanitizer.cleanErrorMessage(error.message, error),
|
||||
};
|
||||
}
|
||||
|
||||
let httpCode =
|
||||
error.status || (error.response && error.response.status) || error.code;
|
||||
|
||||
|
@ -28,7 +28,6 @@ const { XPCOMUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
||||
);
|
||||
const lazy = {};
|
||||
ChromeUtils.defineModuleGetter(lazy, "OS", "resource://gre/modules/osfile.jsm");
|
||||
const FxAccountsCommon = ChromeUtils.import(
|
||||
"resource://gre/modules/FxAccountsCommon.js"
|
||||
);
|
||||
@ -343,7 +342,7 @@ var Utils = {
|
||||
let [fileName] = args.splice(-1);
|
||||
|
||||
return PathUtils.join(
|
||||
Services.dirsvc.get("ProfD", Ci.nsIFile).path,
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
...args,
|
||||
`${fileName}.json`
|
||||
@ -375,9 +374,9 @@ var Utils = {
|
||||
}
|
||||
|
||||
try {
|
||||
return await CommonUtils.readJSON(path);
|
||||
return await IOUtils.readJSON(path);
|
||||
} catch (e) {
|
||||
if (!(e instanceof lazy.OS.File.Error && e.becauseNoSuchFile)) {
|
||||
if (!DOMException.isInstance(e) || e.name !== "NotFoundError") {
|
||||
if (that._log) {
|
||||
that._log.debug("Failed to load json", e);
|
||||
}
|
||||
@ -402,16 +401,14 @@ var Utils = {
|
||||
* Promise resolved when the write has been performed.
|
||||
*/
|
||||
async jsonSave(filePath, that, obj) {
|
||||
let path = lazy.OS.Path.join(
|
||||
lazy.OS.Constants.Path.profileDir,
|
||||
let path = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
...(filePath + ".json").split("/")
|
||||
);
|
||||
let dir = lazy.OS.Path.dirname(path);
|
||||
let dir = PathUtils.parent(path);
|
||||
|
||||
await lazy.OS.File.makeDir(dir, {
|
||||
from: lazy.OS.Constants.Path.profileDir,
|
||||
});
|
||||
await IOUtils.makeDirectory(dir, { createAncestors: true });
|
||||
|
||||
if (that._log) {
|
||||
that._log.trace("Saving json to disk: " + path);
|
||||
@ -419,7 +416,7 @@ var Utils = {
|
||||
|
||||
let json = typeof obj == "function" ? obj.call(that) : obj;
|
||||
|
||||
return CommonUtils.writeJSON(json, path);
|
||||
return IOUtils.writeJSON(path, json);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -474,20 +471,20 @@ var Utils = {
|
||||
* Object to use for logging
|
||||
*/
|
||||
jsonMove(aFrom, aTo, that) {
|
||||
let pathFrom = lazy.OS.Path.join(
|
||||
lazy.OS.Constants.Path.profileDir,
|
||||
let pathFrom = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
...(aFrom + ".json").split("/")
|
||||
);
|
||||
let pathTo = lazy.OS.Path.join(
|
||||
lazy.OS.Constants.Path.profileDir,
|
||||
let pathTo = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
...(aTo + ".json").split("/")
|
||||
);
|
||||
if (that._log) {
|
||||
that._log.trace("Moving " + pathFrom + " to " + pathTo);
|
||||
}
|
||||
return lazy.OS.File.move(pathFrom, pathTo, { noOverwrite: true });
|
||||
return IOUtils.move(pathFrom, pathTo, { noOverwrite: true });
|
||||
},
|
||||
|
||||
/**
|
||||
@ -502,15 +499,15 @@ var Utils = {
|
||||
* Object to use for logging
|
||||
*/
|
||||
jsonRemove(filePath, that) {
|
||||
let path = lazy.OS.Path.join(
|
||||
lazy.OS.Constants.Path.profileDir,
|
||||
let path = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
...(filePath + ".json").split("/")
|
||||
);
|
||||
if (that._log) {
|
||||
that._log.trace("Deleting " + path);
|
||||
}
|
||||
return lazy.OS.File.remove(path, { ignoreAbsent: true });
|
||||
return IOUtils.remove(path, { ignoreAbsent: true });
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@ const { BookmarkHTMLUtils } = ChromeUtils.importESModule(
|
||||
const { BookmarkJSONUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/BookmarkJSONUtils.sys.mjs"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
const {
|
||||
Bookmark,
|
||||
BookmarkFolder,
|
||||
@ -472,8 +471,8 @@ async function test_restoreOrImport(engine, { replace }) {
|
||||
});
|
||||
_(`Get Firefox!: ${bmk1.guid}`);
|
||||
|
||||
let backupFilePath = OS.Path.join(
|
||||
OS.Constants.Path.tmpDir,
|
||||
let backupFilePath = PathUtils.join(
|
||||
PathUtils.tempDir,
|
||||
`t_b_e_${Date.now()}.json`
|
||||
);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
const { PromiseUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/PromiseUtils.jsm"
|
||||
);
|
||||
@ -125,11 +124,9 @@ add_task(async function test_invalidChangedIDs() {
|
||||
let tracker = engine._tracker;
|
||||
|
||||
await tracker._beforeSave();
|
||||
await OS.File.writeAtomic(
|
||||
tracker._storage.path,
|
||||
new TextEncoder().encode("5"),
|
||||
{ tmpPath: tracker._storage.path + ".tmp" }
|
||||
);
|
||||
await IOUtils.writeUTF8(tracker._storage.path, "5", {
|
||||
tmpPath: tracker._storage.path + ".tmp",
|
||||
});
|
||||
|
||||
ok(!tracker._storage.dataReady);
|
||||
const changes = await tracker.getChangedIDs();
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
const { Service } = ChromeUtils.import("resource://services-sync/service.js");
|
||||
|
||||
async function makeSteamEngine() {
|
||||
@ -116,7 +115,6 @@ add_task(async function test_lastSync() {
|
||||
add_task(async function test_toFetch() {
|
||||
_("SyncEngine.toFetch corresponds to file on disk");
|
||||
await SyncTestingInfrastructure(server);
|
||||
const filename = "weave/toFetch/steam.json";
|
||||
|
||||
await testSteamEngineStorage({
|
||||
toFetch: guidSetOfSize(3),
|
||||
@ -153,9 +151,13 @@ add_task(async function test_toFetch() {
|
||||
await testSteamEngineStorage({
|
||||
toFetch: guidSetOfSize(2),
|
||||
async beforeCheck() {
|
||||
let toFetchPath = OS.Path.join(OS.Constants.Path.profileDir, filename);
|
||||
let bytes = new TextEncoder().encode(JSON.stringify(this.toFetch));
|
||||
await OS.File.writeAtomic(toFetchPath, bytes, {
|
||||
let toFetchPath = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
"toFetch",
|
||||
"steam.json"
|
||||
);
|
||||
await IOUtils.writeJSON(toFetchPath, this.toFetch, {
|
||||
tmpPath: toFetchPath + ".tmp",
|
||||
});
|
||||
},
|
||||
@ -169,7 +171,6 @@ add_task(async function test_toFetch() {
|
||||
add_task(async function test_previousFailed() {
|
||||
_("SyncEngine.previousFailed corresponds to file on disk");
|
||||
await SyncTestingInfrastructure(server);
|
||||
const filename = "weave/failed/steam.json";
|
||||
|
||||
await testSteamEngineStorage({
|
||||
previousFailed: guidSetOfSize(3),
|
||||
@ -206,12 +207,13 @@ add_task(async function test_previousFailed() {
|
||||
await testSteamEngineStorage({
|
||||
previousFailed: guidSetOfSize(2),
|
||||
async beforeCheck() {
|
||||
let previousFailedPath = OS.Path.join(
|
||||
OS.Constants.Path.profileDir,
|
||||
filename
|
||||
let previousFailedPath = PathUtils.join(
|
||||
PathUtils.profileDir,
|
||||
"weave",
|
||||
"failed",
|
||||
"steam.json"
|
||||
);
|
||||
let bytes = new TextEncoder().encode(JSON.stringify(this.previousFailed));
|
||||
await OS.File.writeAtomic(previousFailedPath, bytes, {
|
||||
await IOUtils.writeJSON(previousFailedPath, this.previousFailed, {
|
||||
tmpPath: previousFailedPath + ".tmp",
|
||||
});
|
||||
},
|
||||
|
@ -7,7 +7,6 @@ const { Resource } = ChromeUtils.import("resource://services-sync/resource.js");
|
||||
const { RotaryEngine } = ChromeUtils.import(
|
||||
"resource://testing-common/services/sync/rotaryengine.js"
|
||||
);
|
||||
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
const { getFxAccountsSingleton } = ChromeUtils.import(
|
||||
"resource://gre/modules/FxAccounts.jsm"
|
||||
);
|
||||
@ -546,7 +545,7 @@ add_task(async function test_engine_fail_ioerror() {
|
||||
equal(failureReason.name, "unexpectederror");
|
||||
// ensure the profile dir in the exception message has been stripped.
|
||||
ok(
|
||||
!failureReason.error.includes(OS.Constants.Path.profileDir),
|
||||
!failureReason.error.includes(PathUtils.profileDir),
|
||||
failureReason.error
|
||||
);
|
||||
ok(failureReason.error.includes("[profileDir]"), failureReason.error);
|
||||
@ -671,13 +670,10 @@ add_task(async function test_clean_real_os_error() {
|
||||
engine.enabled = true;
|
||||
let server = await serverForFoo(engine);
|
||||
await SyncTestingInfrastructure(server);
|
||||
let path =
|
||||
Services.appinfo.OS == "WINNT"
|
||||
? "no\\such\\path.json"
|
||||
: "no/such/path.json";
|
||||
let path = PathUtils.join(PathUtils.profileDir, "no", "such", "path.json");
|
||||
try {
|
||||
await CommonUtils.writeJSON({}, path);
|
||||
throw new Error("should fail to write the file");
|
||||
await IOUtils.readJSON(path);
|
||||
throw new Error("should fail to read the file");
|
||||
} catch (ex) {
|
||||
engine._errToThrow = ex;
|
||||
}
|
||||
@ -692,7 +688,7 @@ add_task(async function test_clean_real_os_error() {
|
||||
equal(failureReason.name, "unexpectederror");
|
||||
equal(
|
||||
failureReason.error,
|
||||
"OS error [File/Path not found] during operation open on file no/such/path.json"
|
||||
"OS error [File/Path not found] Could not open the file at [profileDir]/no/such/path.json"
|
||||
);
|
||||
});
|
||||
} finally {
|
||||
|
@ -50,7 +50,6 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
JsonSchema: "resource://gre/modules/JsonSchema.jsm",
|
||||
Log: "resource://gre/modules/Log.jsm",
|
||||
Logger: "resource://tps/logger.jsm",
|
||||
OS: "resource://gre/modules/osfile.jsm",
|
||||
SessionStore: "resource:///modules/sessionstore/SessionStore.jsm",
|
||||
Svc: "resource://services-sync/util.js",
|
||||
SyncTelemetry: "resource://services-sync/telemetry.js",
|
||||
@ -1009,7 +1008,8 @@ var TPS = {
|
||||
_getFileRelativeToSourceRoot(testFileURL, relativePath) {
|
||||
let file = lazy.fileProtocolHandler.getFileFromURLSpec(testFileURL);
|
||||
let root = file.parent.parent.parent.parent.parent; // <root>/services/sync/tests/tps/test_foo.js // <root>/services/sync/tests/tps // <root>/services/sync/tests // <root>/services/sync // <root>/services // <root>
|
||||
root.appendRelativePath(lazy.OS.Path.normalize(relativePath));
|
||||
root.appendRelativePath(relativePath);
|
||||
root.normalize();
|
||||
return root;
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user