From 13b1dcf78500081ff349a151e9e5ccb498e33593 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 16 Jan 2023 16:43:45 +0000 Subject: [PATCH] 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. --- src/settings/rageshake.ts | 113 +++++++++++++------------------------- 1 file changed, 39 insertions(+), 74 deletions(-) diff --git a/src/settings/rageshake.ts b/src/settings/rageshake.ts index 42441d1c..f83a205f 100644 --- a/src/settings/rageshake.ts +++ b/src/settings/rageshake.ts @@ -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 2018 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( level: string, ...args: (Error | DOMException | object | string)[] @@ -140,20 +116,22 @@ export class ConsoleLogger { } /** - * Retrieve log lines to flush to disk. - * @param {boolean} keepLogs True to not delete logs after flushing. - * @return {string} \n delimited log lines to flush. + * Returns the log lines to flush to disk and empties the internal log buffer + * @return {string} \n delimited log lines */ - public flush(keepLogs?: boolean): string { - // The ConsoleLogger doesn't care how these end up on disk, it just - // flushes them to the caller. - if (keepLogs) { - return this.logs; - } + public popLogs(): string { const logsToFlush = this.logs; this.logs = ""; 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. @@ -174,30 +152,32 @@ export class IndexedDBLogStore { public connect(): Promise { const req = this.indexedDB.open("logs"); return new Promise((resolve, reject) => { - req.onsuccess = (event: Event) => { - // @ts-ignore - this.db = event.target.result; + req.onsuccess = () => { + this.db = req.result; // Periodically flush logs to local storage / indexeddb setInterval(this.flush.bind(this), FLUSH_RATE_MS); resolve(); }; req.onerror = (event) => { - const err = - // @ts-ignore - "Failed to open log database: " + event.target.error.name; + const err = "Failed to open log database: " + req.error.name; logger.error(err); reject(new Error(err)); }; // First time: Setup the object store req.onupgradeneeded = (event) => { - // @ts-ignore - const db = event.target.result; + const db = req.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", { keyPath: ["id", "index"], }); // 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. // In order to do this, we need to set up indexes "id". logObjStore.createIndex("id", "id", { unique: false }); @@ -206,6 +186,9 @@ export class IndexedDBLogStore { 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", { keyPath: "id", }); @@ -258,7 +241,7 @@ export class IndexedDBLogStore { reject(new Error("No connected database")); return; } - const lines = this.logger.flush(); + const lines = this.logger.popLogs(); if (lines.length === 0) { resolve(); return; @@ -270,8 +253,7 @@ export class IndexedDBLogStore { }; txn.onerror = (event) => { logger.error("Failed to flush logs : ", event); - // @ts-ignore - reject(new Error("Failed to write logs: " + event.target.errorCode)); + reject(new Error("Failed to write logs: " + txn.error.message)); }; objStore.add(this.generateLogEntry(lines)); const lastModStore = txn.objectStore("logslastmod"); @@ -307,13 +289,11 @@ export class IndexedDBLogStore { .index("id") .openCursor(IDBKeyRange.only(id), "prev"); let lines = ""; - query.onerror = (event) => { - // @ts-ignore - reject(new Error("Query failed: " + event.target.errorCode)); + query.onerror = () => { + reject(new Error("Query failed: " + query.error.message)); }; - query.onsuccess = (event) => { - // @ts-ignore - const cursor = event.target.result; + query.onsuccess = () => { + const cursor = query.result; if (!cursor) { resolve(lines); return; // end of results @@ -355,9 +335,8 @@ export class IndexedDBLogStore { const o = txn.objectStore("logs"); // only load the key path, not the data which may be huge const query = o.index("id").openKeyCursor(IDBKeyRange.only(id)); - query.onsuccess = (event) => { - // @ts-ignore - const cursor = event.target.result; + query.onsuccess = () => { + const cursor = query.result; if (!cursor) { return; } @@ -367,12 +346,10 @@ export class IndexedDBLogStore { txn.oncomplete = () => { resolve(); }; - txn.onerror = (event) => { + txn.onerror = () => { reject( new Error( - "Failed to delete logs for " + - // @ts-ignore - `'${id}' : ${event.target.errorCode}` + "Failed to delete logs for " + `'${id}' : ${txn.error.message}` ) ); }; @@ -457,13 +434,11 @@ function selectQuery( return new Promise((resolve, reject) => { const results = []; query.onerror = (event) => { - // @ts-ignore - reject(new Error("Query failed: " + event.target.errorCode)); + reject(new Error("Query failed: " + query.error.message)); }; // collect results query.onsuccess = (event) => { - // @ts-ignore - const cursor = event.target.result; + const cursor = query.result; if (!cursor) { resolve(results); return; // end of results @@ -479,8 +454,6 @@ declare global { // eslint-disable-next-line no-var, camelcase var mx_rage_logger: ConsoleLogger; // eslint-disable-next-line no-var, camelcase - var mx_rage_initPromise: Promise; - // eslint-disable-next-line no-var, camelcase var mx_rage_initStoragePromise: Promise; } @@ -491,19 +464,11 @@ declare global { * be set up immediately for the logs. * @return {Promise} Resolves when set up. */ -export function init(setUpPersistence = true): Promise { - if (global.mx_rage_initPromise) { - return global.mx_rage_initPromise; - } +export function init(): Promise { global.mx_rage_logger = new ConsoleLogger(); global.mx_rage_logger.monkeyPatch(window.console); - if (setUpPersistence) { - return tryInitStorage(); - } - - global.mx_rage_initPromise = Promise.resolve(); - return global.mx_rage_initPromise; + return tryInitStorage(); } /** @@ -573,7 +538,7 @@ export async function getLogsForReport(): Promise { } else { return [ { - lines: global.mx_rage_logger.flush(true), + lines: global.mx_rage_logger.peekLogs(), id: "-", }, ];