зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1529584 - Distinguish Remote Settings errors when reporting uptake r=glasserc
Distinguish Remote Settings errors when reporting uptake Differential Revision: https://phabricator.services.mozilla.com/D20836 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ab16f9127e
Коммит
d19b2d9d78
|
@ -138,6 +138,7 @@ const certBlocklistJSON = `{
|
|||
|
||||
function serveResponse(body) {
|
||||
return (req, response) => {
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
response.write(body);
|
||||
};
|
||||
|
|
|
@ -332,9 +332,8 @@ class RemoteSettingsClient extends EventEmitter {
|
|||
syncResult = await collection.sync({ remote: gServerURL, strategy, expectedTimestamp });
|
||||
const { ok } = syncResult;
|
||||
if (!ok) {
|
||||
// Some synchronization conflicts occured.
|
||||
reportStatus = UptakeTelemetry.STATUS.CONFLICT_ERROR;
|
||||
throw new Error("Sync failed");
|
||||
// With SERVER_WINS, there cannot be any conflicts, but don't silent it anyway.
|
||||
throw new Error("Synced failed");
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.message.includes(INVALID_SIGNATURE)) {
|
||||
|
@ -357,8 +356,14 @@ class RemoteSettingsClient extends EventEmitter {
|
|||
if (e.message == MISSING_SIGNATURE) {
|
||||
// Collection metadata has no signature info, no need to retry.
|
||||
reportStatus = UptakeTelemetry.STATUS.SIGNATURE_ERROR;
|
||||
} else if (/unparseable/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.PARSE_ERROR;
|
||||
} else if (/NetworkError/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.NETWORK_ERROR;
|
||||
} else if (/Timeout/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.TIMEOUT_ERROR;
|
||||
} else if (/HTTP 5??/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.SERVER_ERROR;
|
||||
} else if (/Backoff/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.BACKOFF;
|
||||
} else {
|
||||
|
@ -379,6 +384,10 @@ class RemoteSettingsClient extends EventEmitter {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// IndexedDB errors. See https://developer.mozilla.org/en-US/docs/Web/API/IDBRequest/error
|
||||
if (/(AbortError|ConstraintError|QuotaExceededError|VersionError)/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.CUSTOM_1_ERROR;
|
||||
}
|
||||
// No specific error was tracked, mark it as unknown.
|
||||
if (reportStatus === null) {
|
||||
reportStatus = UptakeTelemetry.STATUS.UNKNOWN_ERROR;
|
||||
|
|
|
@ -82,6 +82,10 @@ var Utils = {
|
|||
let changes = [];
|
||||
// If no changes since last time, go on with empty list of changes.
|
||||
if (response.status != 304) {
|
||||
const ct = response.headers.get("Content-Type");
|
||||
if (!ct || !ct.includes("application/json")) {
|
||||
throw new Error(`Unexpected content-type "${ct}"`);
|
||||
}
|
||||
let payload;
|
||||
try {
|
||||
payload = await response.json();
|
||||
|
|
|
@ -181,8 +181,14 @@ function remoteSettingsFunction() {
|
|||
} catch (e) {
|
||||
// Report polling error to Uptake Telemetry.
|
||||
let reportStatus;
|
||||
if (/Server/.test(e.message)) {
|
||||
if (/JSON\.parse/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.PARSE_ERROR;
|
||||
} else if (/content-type/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.CONTENT_ERROR;
|
||||
} else if (/Server/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.SERVER_ERROR;
|
||||
} else if (/Timeout/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.TIMEOUT_ERROR;
|
||||
} else if (/NetworkError/.test(e.message)) {
|
||||
reportStatus = UptakeTelemetry.STATUS.NETWORK_ERROR;
|
||||
} else {
|
||||
|
|
|
@ -64,7 +64,9 @@ function run_test() {
|
|||
}
|
||||
response.setHeader("Date", (new Date()).toUTCString());
|
||||
|
||||
response.write(JSON.stringify(sample.responseBody));
|
||||
const body = typeof sample.responseBody == "string" ? sample.responseBody
|
||||
: JSON.stringify(sample.responseBody);
|
||||
response.write(body);
|
||||
response.finish();
|
||||
} catch (e) {
|
||||
info(e);
|
||||
|
@ -330,7 +332,39 @@ add_task(async function test_telemetry_reports_if_sync_fails() {
|
|||
} catch (e) {}
|
||||
|
||||
const endHistogram = getUptakeTelemetrySnapshot(client.identifier);
|
||||
const expectedIncrements = {[UptakeTelemetry.STATUS.SYNC_ERROR]: 1};
|
||||
const expectedIncrements = {[UptakeTelemetry.STATUS.SERVER_ERROR]: 1};
|
||||
checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
|
||||
});
|
||||
add_task(clear_state);
|
||||
|
||||
add_task(async function test_telemetry_reports_if_parsing_fails() {
|
||||
const collection = await client.openCollection();
|
||||
await collection.db.saveLastModified(10000);
|
||||
|
||||
const startHistogram = getUptakeTelemetrySnapshot(client.identifier);
|
||||
|
||||
try {
|
||||
await client.maybeSync(10001);
|
||||
} catch (e) { }
|
||||
|
||||
const endHistogram = getUptakeTelemetrySnapshot(client.identifier);
|
||||
const expectedIncrements = { [UptakeTelemetry.STATUS.PARSE_ERROR]: 1 };
|
||||
checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
|
||||
});
|
||||
add_task(clear_state);
|
||||
|
||||
add_task(async function test_telemetry_reports_if_fetching_signature_fails() {
|
||||
const collection = await client.openCollection();
|
||||
await collection.db.saveLastModified(11000);
|
||||
|
||||
const startHistogram = getUptakeTelemetrySnapshot(client.identifier);
|
||||
|
||||
try {
|
||||
await client.maybeSync(11001);
|
||||
} catch (e) { }
|
||||
|
||||
const endHistogram = getUptakeTelemetrySnapshot(client.identifier);
|
||||
const expectedIncrements = { [UptakeTelemetry.STATUS.SERVER_ERROR]: 1 };
|
||||
checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
|
||||
});
|
||||
add_task(clear_state);
|
||||
|
@ -526,6 +560,48 @@ function getSampleResponse(req, port) {
|
|||
error: "Service Unavailable",
|
||||
},
|
||||
},
|
||||
"GET:/v1/buckets/main/collections/password-fields/records?_expected=10001&_sort=-last_modified&_since=10000": {
|
||||
"sampleHeaders": [
|
||||
"Access-Control-Allow-Origin: *",
|
||||
"Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",
|
||||
"Content-Type: application/json; charset=UTF-8",
|
||||
"Server: waitress",
|
||||
"Etag: \"10001\"",
|
||||
],
|
||||
"status": { status: 200, statusText: "OK" },
|
||||
"responseBody": "<invalid json",
|
||||
},
|
||||
"GET:/v1/buckets/main/collections/password-fields/records?_expected=11001&_sort=-last_modified&_since=11000": {
|
||||
"sampleHeaders": [
|
||||
"Access-Control-Allow-Origin: *",
|
||||
"Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",
|
||||
"Content-Type: application/json; charset=UTF-8",
|
||||
"Server: waitress",
|
||||
],
|
||||
"status": { status: 503, statusText: "Service Unavailable" },
|
||||
"responseBody": {
|
||||
"data": [{
|
||||
"id": "c4f021e3-f68c-4269-ad2a-d4ba87762b35",
|
||||
"last_modified": 4000,
|
||||
"website": "https://www.eff.org",
|
||||
"selector": "#pwd",
|
||||
}],
|
||||
},
|
||||
},
|
||||
"GET:/v1/buckets/main/collections/password-fields?_expected=11001": {
|
||||
"sampleHeaders": [
|
||||
"Access-Control-Allow-Origin: *",
|
||||
"Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff",
|
||||
"Content-Type: application/json; charset=UTF-8",
|
||||
"Server: waitress",
|
||||
],
|
||||
"status": { status: 503, statusText: "Service Unavailable" },
|
||||
"responseBody": {
|
||||
code: 503,
|
||||
errno: 999,
|
||||
error: "Service Unavailable",
|
||||
},
|
||||
},
|
||||
"GET:/v1/buckets/monitor/collections/changes/records?collection=password-fields&bucket=main": {
|
||||
"sampleHeaders": [
|
||||
"Access-Control-Allow-Origin: *",
|
||||
|
|
|
@ -63,6 +63,7 @@ add_task(clear_state);
|
|||
add_task(async function test_an_event_is_sent_on_start() {
|
||||
server.registerPathHandler(CHANGES_PATH, (request, response) => {
|
||||
response.write(JSON.stringify({ data: [] }));
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.setHeader("ETag", '"42"');
|
||||
response.setHeader("Date", (new Date()).toUTCString());
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
|
@ -235,6 +236,7 @@ add_task(async function test_expected_timestamp() {
|
|||
data: entries,
|
||||
}));
|
||||
}
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.setHeader("ETag", '"1100"');
|
||||
response.setHeader("Date", (new Date()).toUTCString());
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
|
@ -263,6 +265,7 @@ add_task(async function test_client_last_check_is_saved() {
|
|||
collection: "models-recipes",
|
||||
}],
|
||||
}));
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.setHeader("ETag", '"42"');
|
||||
response.setHeader("Date", (new Date()).toUTCString());
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
|
@ -307,6 +310,7 @@ add_task(async function test_success_with_partial_list() {
|
|||
}));
|
||||
response.setHeader("ETag", '"42"');
|
||||
}
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.setHeader("Date", (new Date()).toUTCString());
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
}
|
||||
|
@ -327,6 +331,8 @@ add_task(clear_state);
|
|||
|
||||
|
||||
add_task(async function test_server_bad_json() {
|
||||
const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
|
||||
|
||||
function simulateBadJSON(request, response) {
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.write("<html></html>");
|
||||
|
@ -341,6 +347,39 @@ add_task(async function test_server_bad_json() {
|
|||
error = e;
|
||||
}
|
||||
Assert.ok(/JSON.parse: unexpected character/.test(error.message));
|
||||
|
||||
const endHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
|
||||
const expectedIncrements = {
|
||||
[UptakeTelemetry.STATUS.PARSE_ERROR]: 1,
|
||||
};
|
||||
checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
|
||||
});
|
||||
add_task(clear_state);
|
||||
|
||||
|
||||
add_task(async function test_server_bad_content_type() {
|
||||
const startHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
|
||||
|
||||
function simulateBadContentType(request, response) {
|
||||
response.setHeader("Content-Type", "text/html");
|
||||
response.write("<html></html>");
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
}
|
||||
server.registerPathHandler(CHANGES_PATH, simulateBadContentType);
|
||||
|
||||
let error;
|
||||
try {
|
||||
await RemoteSettings.pollChanges();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
Assert.ok(/Unexpected content-type/.test(error.message));
|
||||
|
||||
const endHistogram = getUptakeTelemetrySnapshot(TELEMETRY_HISTOGRAM_KEY);
|
||||
const expectedIncrements = {
|
||||
[UptakeTelemetry.STATUS.CONTENT_ERROR]: 1,
|
||||
};
|
||||
checkUptakeTelemetry(startHistogram, endHistogram, expectedIncrements);
|
||||
});
|
||||
add_task(clear_state);
|
||||
|
||||
|
@ -640,6 +679,7 @@ add_task(async function test_adding_client_resets_last_etag() {
|
|||
response.setHeader("ETag", '"42"');
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
}
|
||||
response.setHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
response.setHeader("Date", (new Date()).toUTCString());
|
||||
}
|
||||
server.registerPathHandler(CHANGES_PATH, serve200or304);
|
||||
|
|
Загрузка…
Ссылка в новой задаче