Mostly cosmetic fixes to rageshake

* Remove duplicate copyright header
 * Remove ts-ignores by just using the objects directly rather than via
   event.target
 * Use error.message rather than errorCode which TS doesn't know about
   and may or may not exist.
 * Remove some unused things like the skip rageshake function and
   the option to init rageshakes without storage.
 * Turn single function with a boolean param to make it take two entirely
   separate code paths into two functions.
This commit is contained in:
David Baker
2023-01-16 16:43:45 +00:00
parent 035498a8eb
commit 13b1dcf785

View File

@@ -1,21 +1,4 @@
/* /*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/* eslint-disable @typescript-eslint/ban-ts-comment */
/*
Copyright 2017 OpenMarket Ltd Copyright 2017 OpenMarket Ltd
Copyright 2018 New Vector Ltd Copyright 2018 New Vector Ltd
Copyright 2019 The New Vector Ltd Copyright 2019 The New Vector Ltd
@@ -99,13 +82,6 @@ export class ConsoleLogger {
}); });
} }
public bypassRageshake(
fnName: LogFunctionName,
...args: (Error | DOMException | object | string)[]
): void {
this.originalFunctions[fnName](...args);
}
public log( public log(
level: string, level: string,
...args: (Error | DOMException | object | string)[] ...args: (Error | DOMException | object | string)[]
@@ -140,20 +116,22 @@ export class ConsoleLogger {
} }
/** /**
* Retrieve log lines to flush to disk. * Returns the log lines to flush to disk and empties the internal log buffer
* @param {boolean} keepLogs True to not delete logs after flushing. * @return {string} \n delimited log lines
* @return {string} \n delimited log lines to flush.
*/ */
public flush(keepLogs?: boolean): string { public popLogs(): string {
// The ConsoleLogger doesn't care how these end up on disk, it just
// flushes them to the caller.
if (keepLogs) {
return this.logs;
}
const logsToFlush = this.logs; const logsToFlush = this.logs;
this.logs = ""; this.logs = "";
return logsToFlush; return logsToFlush;
} }
/**
* Returns lines currently in the log buffer without removing them
* @return {string} \n delimited log lines
*/
public peekLogs(): string {
return this.logs;
}
} }
// A class which stores log lines in an IndexedDB instance. // A class which stores log lines in an IndexedDB instance.
@@ -174,30 +152,32 @@ export class IndexedDBLogStore {
public connect(): Promise<void> { public connect(): Promise<void> {
const req = this.indexedDB.open("logs"); const req = this.indexedDB.open("logs");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
req.onsuccess = (event: Event) => { req.onsuccess = () => {
// @ts-ignore this.db = req.result;
this.db = event.target.result;
// Periodically flush logs to local storage / indexeddb // Periodically flush logs to local storage / indexeddb
setInterval(this.flush.bind(this), FLUSH_RATE_MS); setInterval(this.flush.bind(this), FLUSH_RATE_MS);
resolve(); resolve();
}; };
req.onerror = (event) => { req.onerror = (event) => {
const err = const err = "Failed to open log database: " + req.error.name;
// @ts-ignore
"Failed to open log database: " + event.target.error.name;
logger.error(err); logger.error(err);
reject(new Error(err)); reject(new Error(err));
}; };
// First time: Setup the object store // First time: Setup the object store
req.onupgradeneeded = (event) => { req.onupgradeneeded = (event) => {
// @ts-ignore const db = req.result;
const db = event.target.result; // This is the log entries themselves. Each entry is a chunk of
// logs (ie multiple lines). 'id' is the instance ID (so logs with
// the same instance ID are all from the same session) and 'index'
// is a sequence number for the chunk. The log lines live in the
// 'lines' key, which is a chunk of many newline-separated log lines.
const logObjStore = db.createObjectStore("logs", { const logObjStore = db.createObjectStore("logs", {
keyPath: ["id", "index"], keyPath: ["id", "index"],
}); });
// Keys in the database look like: [ "instance-148938490", 0 ] // Keys in the database look like: [ "instance-148938490", 0 ]
// (The instance ID plus the ID of each log chunk).
// Later on we need to query everything based on an instance id. // Later on we need to query everything based on an instance id.
// In order to do this, we need to set up indexes "id". // In order to do this, we need to set up indexes "id".
logObjStore.createIndex("id", "id", { unique: false }); logObjStore.createIndex("id", "id", { unique: false });
@@ -206,6 +186,9 @@ export class IndexedDBLogStore {
this.generateLogEntry(new Date() + " ::: Log database was created.") this.generateLogEntry(new Date() + " ::: Log database was created.")
); );
// This records the last time each instance ID generated a log message, such
// that the logs from each session can be collated in the order they last logged
// something.
const lastModifiedStore = db.createObjectStore("logslastmod", { const lastModifiedStore = db.createObjectStore("logslastmod", {
keyPath: "id", keyPath: "id",
}); });
@@ -258,7 +241,7 @@ export class IndexedDBLogStore {
reject(new Error("No connected database")); reject(new Error("No connected database"));
return; return;
} }
const lines = this.logger.flush(); const lines = this.logger.popLogs();
if (lines.length === 0) { if (lines.length === 0) {
resolve(); resolve();
return; return;
@@ -270,8 +253,7 @@ export class IndexedDBLogStore {
}; };
txn.onerror = (event) => { txn.onerror = (event) => {
logger.error("Failed to flush logs : ", event); logger.error("Failed to flush logs : ", event);
// @ts-ignore reject(new Error("Failed to write logs: " + txn.error.message));
reject(new Error("Failed to write logs: " + event.target.errorCode));
}; };
objStore.add(this.generateLogEntry(lines)); objStore.add(this.generateLogEntry(lines));
const lastModStore = txn.objectStore("logslastmod"); const lastModStore = txn.objectStore("logslastmod");
@@ -307,13 +289,11 @@ export class IndexedDBLogStore {
.index("id") .index("id")
.openCursor(IDBKeyRange.only(id), "prev"); .openCursor(IDBKeyRange.only(id), "prev");
let lines = ""; let lines = "";
query.onerror = (event) => { query.onerror = () => {
// @ts-ignore reject(new Error("Query failed: " + query.error.message));
reject(new Error("Query failed: " + event.target.errorCode));
}; };
query.onsuccess = (event) => { query.onsuccess = () => {
// @ts-ignore const cursor = query.result;
const cursor = event.target.result;
if (!cursor) { if (!cursor) {
resolve(lines); resolve(lines);
return; // end of results return; // end of results
@@ -355,9 +335,8 @@ export class IndexedDBLogStore {
const o = txn.objectStore("logs"); const o = txn.objectStore("logs");
// only load the key path, not the data which may be huge // only load the key path, not the data which may be huge
const query = o.index("id").openKeyCursor(IDBKeyRange.only(id)); const query = o.index("id").openKeyCursor(IDBKeyRange.only(id));
query.onsuccess = (event) => { query.onsuccess = () => {
// @ts-ignore const cursor = query.result;
const cursor = event.target.result;
if (!cursor) { if (!cursor) {
return; return;
} }
@@ -367,12 +346,10 @@ export class IndexedDBLogStore {
txn.oncomplete = () => { txn.oncomplete = () => {
resolve(); resolve();
}; };
txn.onerror = (event) => { txn.onerror = () => {
reject( reject(
new Error( new Error(
"Failed to delete logs for " + "Failed to delete logs for " + `'${id}' : ${txn.error.message}`
// @ts-ignore
`'${id}' : ${event.target.errorCode}`
) )
); );
}; };
@@ -457,13 +434,11 @@ function selectQuery<T>(
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const results = []; const results = [];
query.onerror = (event) => { query.onerror = (event) => {
// @ts-ignore reject(new Error("Query failed: " + query.error.message));
reject(new Error("Query failed: " + event.target.errorCode));
}; };
// collect results // collect results
query.onsuccess = (event) => { query.onsuccess = (event) => {
// @ts-ignore const cursor = query.result;
const cursor = event.target.result;
if (!cursor) { if (!cursor) {
resolve(results); resolve(results);
return; // end of results return; // end of results
@@ -479,8 +454,6 @@ declare global {
// eslint-disable-next-line no-var, camelcase // eslint-disable-next-line no-var, camelcase
var mx_rage_logger: ConsoleLogger; var mx_rage_logger: ConsoleLogger;
// eslint-disable-next-line no-var, camelcase // eslint-disable-next-line no-var, camelcase
var mx_rage_initPromise: Promise<void>;
// eslint-disable-next-line no-var, camelcase
var mx_rage_initStoragePromise: Promise<void>; var mx_rage_initStoragePromise: Promise<void>;
} }
@@ -491,19 +464,11 @@ declare global {
* be set up immediately for the logs. * be set up immediately for the logs.
* @return {Promise} Resolves when set up. * @return {Promise} Resolves when set up.
*/ */
export function init(setUpPersistence = true): Promise<void> { export function init(): Promise<void> {
if (global.mx_rage_initPromise) {
return global.mx_rage_initPromise;
}
global.mx_rage_logger = new ConsoleLogger(); global.mx_rage_logger = new ConsoleLogger();
global.mx_rage_logger.monkeyPatch(window.console); global.mx_rage_logger.monkeyPatch(window.console);
if (setUpPersistence) { return tryInitStorage();
return tryInitStorage();
}
global.mx_rage_initPromise = Promise.resolve();
return global.mx_rage_initPromise;
} }
/** /**
@@ -573,7 +538,7 @@ export async function getLogsForReport(): Promise<LogEntry[]> {
} else { } else {
return [ return [
{ {
lines: global.mx_rage_logger.flush(true), lines: global.mx_rage_logger.peekLogs(),
id: "-", id: "-",
}, },
]; ];