Bug 1727487 - Notify observers of synchronization errors (r=mixedpuppy)

Differential Revision: https://phabricator.services.mozilla.com/D123597
This commit is contained in:
Mathieu Leplatre 2021-08-25 16:45:42 +00:00
Родитель 6d8a72603f
Коммит f225d7e930
3 изменённых файлов: 39 добавлений и 18 удалений

Просмотреть файл

@ -324,6 +324,8 @@ The polling for changes process sends two notifications that observers can regis
* ``remote-settings:changes-poll-start``: Polling for changes is starting. triggered either by the scheduled timer or a push broadcast.
* ``remote-settings:changes-poll-end``: Polling for changes has ended
* ``remote-settings:sync-error``: A synchronization error occured. Notification subject provides information about the error and affected
collection in the ``wrappedJSObject`` attribute.
.. code-block:: javascript

Просмотреть файл

@ -342,6 +342,11 @@ function remoteSettingsFunction() {
UptakeTelemetry.STATUS.SYNC_ERROR,
syncTelemetryArgs
);
// Notify potential observers of the error.
Services.obs.notifyObservers(
{ wrappedJSObject: { error: firstError } },
"remote-settings:sync-error"
);
// Rethrow the first observed error
throw firstError;
}

Просмотреть файл

@ -723,34 +723,34 @@ add_task(async function test_client_error() {
TELEMETRY_HISTOGRAM_SYNC_KEY
);
server.registerPathHandler(
CHANGES_PATH,
serveChangesEntries(10000, [
{
const collectionDetails = {
id: "b6ba7fab-a40a-4d03-a4af-6b627f3c5b36",
last_modified: 42,
host: "localhost",
bucket: "main",
collection: "some-entry",
},
])
};
server.registerPathHandler(
CHANGES_PATH,
serveChangesEntries(10000, [collectionDetails])
);
const c = RemoteSettings("some-entry");
c.maybeSync = () => {
throw new Error("boom");
throw new RemoteSettingsClient.CorruptedDataError("main/some-entry");
};
let notificationObserved = false;
let notificationsObserved = [];
const observer = {
observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, "remote-settings:changes-poll-end");
notificationObserved = true;
Services.obs.removeObserver(this, aTopic);
notificationsObserved.push([aTopic, aSubject.wrappedJSObject]);
},
};
Services.obs.addObserver(observer, "remote-settings:changes-poll-end");
Services.obs.addObserver(observer, "remote-settings:sync-error");
Services.prefs.setIntPref(PREF_LAST_ETAG, 42);
// pollChanges() fails with adequate error and no notification.
// pollChanges() fails with adequate error and a sync-error notification.
let error;
try {
await RemoteSettings.pollChanges();
@ -758,11 +758,25 @@ add_task(async function test_client_error() {
error = e;
}
Assert.ok(
!notificationObserved,
"a notification should not have been observed"
Assert.equal(
notificationsObserved.length,
1,
"only the error notification should not have been observed"
);
Assert.ok(/boom/.test(error.message), "original client error is thrown");
console.log(notificationsObserved);
let [topicObserved, subjectObserved] = notificationsObserved[0];
Assert.equal(topicObserved, "remote-settings:sync-error");
Assert.ok(
subjectObserved.error instanceof RemoteSettingsClient.CorruptedDataError,
`original error is provided (got ${subjectObserved.error})`
);
Assert.deepEqual(
subjectObserved.error.details,
collectionDetails,
"information about collection is provided"
);
Assert.ok(/Corrupted/.test(error.message), "original client error is thrown");
// When an error occurs, last etag was not overwritten.
Assert.equal(Services.prefs.getIntPref(PREF_LAST_ETAG), 42);
// ensure that we've accumulated the correct telemetry