diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-02-14 17:52:01 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-14 17:52:01 -0500 | 
| commit | 9279ced68660610764931da681f22c8b71bf1b6e (patch) | |
| tree | 2a4d015cf57adfe74af72615bad19c9308388e99 | |
| parent | 286534e648af350d24fbf3c7892a7ec81aaeb4bd (diff) | |
Log refactoring (#1393)
* Create Logger class and log instance
* Replace yomichan.logWarning with log.warn
* Replace yomichan.logError with log.error
* Replace yomichan.log with log.log
* Update the Yomichan class to use the global log object
* Update lint rules
26 files changed, 144 insertions, 96 deletions
| diff --git a/.eslintrc.json b/.eslintrc.json index e2197916..fca1449b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -111,9 +111,11 @@                  "deepEqual": "readonly",                  "generateId": "readonly",                  "promiseAnimationFrame": "readonly", +                "log": "readonly",                  "DynamicProperty": "readonly",                  "EventDispatcher": "readonly", -                "EventListenerCollection": "readonly" +                "EventListenerCollection": "readonly", +                "Logger": "readonly"              }          },          { diff --git a/ext/js/app/content-script-main.js b/ext/js/app/content-script-main.js index a09e52ea..1c0c6d49 100644 --- a/ext/js/app/content-script-main.js +++ b/ext/js/app/content-script-main.js @@ -52,6 +52,6 @@          yomichan.ready();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js index 74cc63d2..02707f41 100644 --- a/ext/js/app/frontend.js +++ b/ext/js/app/frontend.js @@ -276,7 +276,7 @@ class Frontend {                      this._showExtensionUnloaded(textSource);                  }              } else { -                yomichan.logError(error); +                log.error(error);              }          } if (type !== null) {              this._stopClearSelectionDelayed(); @@ -563,7 +563,7 @@ class Frontend {          );          this._lastShowPromise.catch((error) => {              if (yomichan.isExtensionUnloaded) { return; } -            yomichan.logError(error); +            log.error(error);          });          return this._lastShowPromise;      } diff --git a/ext/js/app/popup-proxy.js b/ext/js/app/popup-proxy.js index 19856e3f..63ecc254 100644 --- a/ext/js/app/popup-proxy.js +++ b/ext/js/app/popup-proxy.js @@ -201,7 +201,7 @@ class PopupProxy extends EventDispatcher {              }              this._frameOffsetUpdatedAt = now;          } catch (e) { -            yomichan.logError(e); +            log.error(e);          } finally {              this._frameOffsetPromise = null;          } diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index 69c90aca..698724fc 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -204,7 +204,7 @@ class Backend {              try {                  await this._dictionaryDatabase.prepare();              } catch (e) { -                yomichan.logError(e); +                log.error(e);              }              const deinflectionReasions = await this._fetchAsset('/data/deinflect.json', true); @@ -226,7 +226,7 @@ class Backend {              this._sendMessageAllTabsIgnoreResponse('backendReady', {});              this._sendMessageIgnoreResponse({action: 'backendReady', params: {}});          } catch (e) { -            yomichan.logError(e); +            log.error(e);              throw e;          } finally {              if (this._badgePrepareDelayTimer !== null) { @@ -358,7 +358,7 @@ class Backend {              forwardPort.onDisconnect.addListener(cleanup);          } catch (e) {              port.disconnect(); -            yomichan.logError(e); +            log.error(e);          }      } @@ -612,7 +612,7 @@ class Backend {      }      _onApiLog({error, level, context}) { -        yomichan.log(deserializeError(error), level, context); +        log.log(deserializeError(error), level, context);      }      _onApiLogIndicatorClear() { diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js index 997249c8..7dbfb411 100644 --- a/ext/js/comm/cross-frame-api.js +++ b/ext/js/comm/cross-frame-api.js @@ -111,7 +111,7 @@ class CrossFrameAPIPort extends EventDispatcher {      _onAck(id) {          const invocation = this._activeInvocations.get(id);          if (typeof invocation === 'undefined') { -            yomichan.logWarning(new Error(`Request ${id} not found for acknowledgement`)); +            log.warn(new Error(`Request ${id} not found for acknowledgement`));              return;          } @@ -140,7 +140,7 @@ class CrossFrameAPIPort extends EventDispatcher {      _onResult(id, data) {          const invocation = this._activeInvocations.get(id);          if (typeof invocation === 'undefined') { -            yomichan.logWarning(new Error(`Request ${id} not found`)); +            log.warn(new Error(`Request ${id} not found`));              return;          } @@ -269,7 +269,7 @@ class CrossFrameAPI {              this._setupCommPort(otherTabId, otherFrameId, port);          } catch (e) {              port.disconnect(); -            yomichan.logError(e); +            log.error(e);          }      } diff --git a/ext/js/core.js b/ext/js/core.js index 9305739a..4384d9f0 100644 --- a/ext/js/core.js +++ b/ext/js/core.js @@ -607,3 +607,111 @@ class DynamicProperty extends EventDispatcher {          this.trigger('change', {value});      }  } + +/** + * This class handles logging of messages to the console and triggering + * an event for log calls. + */ +class Logger extends EventDispatcher { +    /** +     * Creates a new instance. +     */ +    constructor() { +        super(); +        this._extensionName = 'Yomichan'; +        try { +            const {name, version} = chrome.runtime.getManifest(); +            this._extensionName = `${name} ${version}`; +        } catch (e) { +            // NOP +        } +    } + +    /** +     * Logs a generic error. This will trigger the 'log' event with the same arguments as the function invocation. +     * @param error The error to log. This is typically an `Error` or `Error`-like object. +     * @param level The level to log at. Values include `'info'`, `'debug'`, `'warn'`, and `'error'`. +     *   Other values will be logged at a non-error level. +     * @param context An optional context object for the error which should typically include a `url` field. +     */ +    log(error, level, context=null) { +        if (!isObject(context)) { +            context = {url: location.href}; +        } + +        let errorString; +        try { +            if (typeof error === 'string') { +                errorString = error; +            } else { +                errorString = error.toString(); +                if (/^\[object \w+\]$/.test(errorString)) { +                    errorString = JSON.stringify(error); +                } +            } +        } catch (e) { +            errorString = `${error}`; +        } + +        let errorStack; +        try { +            errorStack = (typeof error.stack === 'string' ? error.stack.trimRight() : ''); +        } catch (e) { +            errorStack = ''; +        } + +        let errorData; +        try { +            errorData = error.data; +        } catch (e) { +            // NOP +        } + +        if (errorStack.startsWith(errorString)) { +            errorString = errorStack; +        } else if (errorStack.length > 0) { +            errorString += `\n${errorStack}`; +        } + +        let message = `${this._extensionName} has encountered a problem.`; +        message += `\nOriginating URL: ${context.url}\n`; +        message += errorString; +        if (typeof errorData !== 'undefined') { +            message += `\nData: ${JSON.stringify(errorData, null, 4)}`; +        } +        message += '\n\nIssues can be reported at https://github.com/FooSoft/yomichan/issues'; + +        switch (level) { +            case 'info': console.info(message); break; +            case 'debug': console.debug(message); break; +            case 'warn': console.warn(message); break; +            case 'error': console.error(message); break; +            default: console.log(message); break; +        } + +        this.trigger('log', {error, level, context}); +    } + +    /** +     * Logs a warning. This function invokes `log` internally. +     * @param error The error to log. This is typically an `Error` or `Error`-like object. +     * @param context An optional context object for the error which should typically include a `url` field. +     */ +    warn(error, context=null) { +        this.log(error, 'warn', context); +    } + +    /** +     * Logs an error. This function invokes `log` internally. +     * @param error The error to log. This is typically an `Error` or `Error`-like object. +     * @param context An optional context object for the error which should typically include a `url` field. +     */ +    error(error, context=null) { +        this.log(error, 'error', context); +    } +} + +/** + * This object is the default logger used by the runtime. + */ +const log = new Logger(); diff --git a/ext/js/display/display.js b/ext/js/display/display.js index 553c17e7..b7477bb8 100644 --- a/ext/js/display/display.js +++ b/ext/js/display/display.js @@ -272,7 +272,7 @@ class Display extends EventDispatcher {      onError(error) {          if (yomichan.isExtensionUnloaded) { return; } -        yomichan.logError(error); +        log.error(error);      }      getOptions() { @@ -1552,7 +1552,7 @@ class Display extends EventDispatcher {                  }                  await this._frontendSetupPromise;              } catch (e) { -                yomichan.logError(e); +                log.error(e);                  return;              } finally {                  this._frontendSetupPromise = null; @@ -1721,7 +1721,7 @@ class Display extends EventDispatcher {      _onDefinitionTextScannerSearched({type, definitions, sentence, textSource, optionsContext, error}) {          if (error !== null && !yomichan.isExtensionUnloaded) { -            yomichan.logError(error); +            log.error(error);          }          if (type === null) { return; } diff --git a/ext/js/display/popup-main.js b/ext/js/display/popup-main.js index 24be6c01..55f19984 100644 --- a/ext/js/display/popup-main.js +++ b/ext/js/display/popup-main.js @@ -49,6 +49,6 @@          yomichan.ready();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/display/query-parser.js b/ext/js/display/query-parser.js index 29401657..d6a3b4da 100644 --- a/ext/js/display/query-parser.js +++ b/ext/js/display/query-parser.js @@ -89,7 +89,7 @@ class QueryParser extends EventDispatcher {      _onSearched(e) {          const {error} = e;          if (error !== null) { -            yomichan.logError(error); +            log.error(error);              return;          }          if (e.type === null) { return; } diff --git a/ext/js/display/search-main.js b/ext/js/display/search-main.js index 08645833..5ad50500 100644 --- a/ext/js/display/search-main.js +++ b/ext/js/display/search-main.js @@ -50,6 +50,6 @@          yomichan.ready();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/general/task-accumulator.js b/ext/js/general/task-accumulator.js index 82691b43..3f3d8ff7 100644 --- a/ext/js/general/task-accumulator.js +++ b/ext/js/general/task-accumulator.js @@ -69,7 +69,7 @@ class TaskAccumulator {              ];              await this._runTasks(allTasks);          } catch (e) { -            yomichan.logError(e); +            log.error(e);          }      } diff --git a/ext/js/language/dictionary-database.js b/ext/js/language/dictionary-database.js index b363ed25..62c22289 100644 --- a/ext/js/language/dictionary-database.js +++ b/ext/js/language/dictionary-database.js @@ -122,7 +122,7 @@ class DictionaryDatabase {              await Database.deleteDatabase(this._dbName);              result = true;          } catch (e) { -            yomichan.logError(e); +            log.error(e);          }          await this.prepare();          return result; diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js index e91498ba..073b1a6c 100644 --- a/ext/js/language/text-scanner.js +++ b/ext/js/language/text-scanner.js @@ -830,7 +830,7 @@ class TextScanner extends EventDispatcher {                  }              }          } catch (e) { -            yomichan.logError(e); +            log.error(e);          } finally {              this._pendingLookup = false;          } diff --git a/ext/js/pages/info-main.js b/ext/js/pages/info-main.js index 45c28d25..ca7d792e 100644 --- a/ext/js/pages/info-main.js +++ b/ext/js/pages/info-main.js @@ -120,6 +120,6 @@ function getOperatingSystemDisplayName(os) {          document.documentElement.dataset.loaded = 'true';      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/pages/permissions-main.js b/ext/js/pages/permissions-main.js index 0cb37e93..782ea9ec 100644 --- a/ext/js/pages/permissions-main.js +++ b/ext/js/pages/permissions-main.js @@ -96,6 +96,6 @@ function setupPermissionsToggles() {          document.documentElement.dataset.loaded = 'true';      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js index 5a6bb2a5..27d0af6a 100644 --- a/ext/js/pages/welcome-main.js +++ b/ext/js/pages/welcome-main.js @@ -81,6 +81,6 @@ async function setupGenericSettingsController(genericSettingController) {          const settingsDisplayController = new SettingsDisplayController(settingsController, modalController);          settingsDisplayController.prepare();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/settings/anki-controller.js b/ext/js/settings/anki-controller.js index db3e3c14..26cab68f 100644 --- a/ext/js/settings/anki-controller.js +++ b/ext/js/settings/anki-controller.js @@ -638,7 +638,7 @@ class AnkiCardController {          try {              await this._settingsController.permissionsUtil.setPermissionsGranted({permissions}, true);          } catch (e) { -            yomichan.logError(e); +            log.error(e);          }      } diff --git a/ext/js/settings/backup-controller.js b/ext/js/settings/backup-controller.js index 117f2422..649645d4 100644 --- a/ext/js/settings/backup-controller.js +++ b/ext/js/settings/backup-controller.js @@ -173,7 +173,7 @@ class BackupController {      }      _showSettingsImportError(error) { -        yomichan.logError(error); +        log.error(error);          document.querySelector('#settings-import-error-message').textContent = `${error}`;          this._settingsImportErrorModal.setVisible(true);      } @@ -412,7 +412,7 @@ class BackupController {          try {              await this._settingsImportSetOptionsFull(optionsFull);          } catch (e) { -            yomichan.logError(e); +            log.error(e);          }      }  } diff --git a/ext/js/settings/dictionary-controller.js b/ext/js/settings/dictionary-controller.js index 78173202..e12017f2 100644 --- a/ext/js/settings/dictionary-controller.js +++ b/ext/js/settings/dictionary-controller.js @@ -476,7 +476,7 @@ class DictionaryController {              await this._deleteDictionaryInternal(dictionaryTitle, onProgress);              await this._deleteDictionarySettings(dictionaryTitle);          } catch (e) { -            yomichan.logError(e); +            log.error(e);          } finally {              prevention.end();              for (const progress of progressContainers) { progress.hidden = true; } diff --git a/ext/js/settings/dictionary-import-controller.js b/ext/js/settings/dictionary-import-controller.js index 00eb7b95..1389b7f0 100644 --- a/ext/js/settings/dictionary-import-controller.js +++ b/ext/js/settings/dictionary-import-controller.js @@ -253,7 +253,7 @@ class DictionaryImportController {      _showErrors(errors) {          const uniqueErrors = new Map();          for (const error of errors) { -            yomichan.logError(error); +            log.error(error);              const errorString = this._errorToString(error);              let count = uniqueErrors.get(errorString);              if (typeof count === 'undefined') { diff --git a/ext/js/settings/main.js b/ext/js/settings/main.js index 51cd5f27..9785ee0e 100644 --- a/ext/js/settings/main.js +++ b/ext/js/settings/main.js @@ -104,6 +104,6 @@ async function setupEnvironmentInfo() {          yomichan.ready();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/settings/pitch-accents-preview-main.js b/ext/js/settings/pitch-accents-preview-main.js index fe3bd36d..d9d56727 100644 --- a/ext/js/settings/pitch-accents-preview-main.js +++ b/ext/js/settings/pitch-accents-preview-main.js @@ -30,6 +30,6 @@          await displayGenerator.prepare();          displayGenerator.preparePitchAccents();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/settings/popup-preview-frame-main.js b/ext/js/settings/popup-preview-frame-main.js index a62e8d28..80e248be 100644 --- a/ext/js/settings/popup-preview-frame-main.js +++ b/ext/js/settings/popup-preview-frame-main.js @@ -38,6 +38,6 @@          document.documentElement.dataset.loaded = 'true';      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/settings/settings-main.js b/ext/js/settings/settings-main.js index a5bb642c..273142cd 100644 --- a/ext/js/settings/settings-main.js +++ b/ext/js/settings/settings-main.js @@ -149,6 +149,6 @@ async function setupGenericSettingsController(genericSettingController) {          const settingsDisplayController = new SettingsDisplayController(settingsController, modalController);          settingsDisplayController.prepare();      } catch (e) { -        yomichan.logError(e); +        log.error(e);      }  })(); diff --git a/ext/js/yomichan.js b/ext/js/yomichan.js index 73deeab9..107694e9 100644 --- a/ext/js/yomichan.js +++ b/ext/js/yomichan.js @@ -103,7 +103,7 @@ class Yomichan extends EventDispatcher {              this.sendMessage({action: 'requestBackendReadySignal'});              await this._isBackendReadyPromise; -            this.on('log', this._onForwardLog.bind(this)); +            log.on('log', this._onForwardLog.bind(this));          }      } @@ -156,68 +156,6 @@ class Yomichan extends EventDispatcher {          });      } -    logWarning(error) { -        this.log(error, 'warn'); -    } - -    logError(error) { -        this.log(error, 'error'); -    } - -    log(error, level, context=null) { -        if (!isObject(context)) { -            context = this._getLogContext(); -        } - -        let errorString; -        try { -            errorString = error.toString(); -            if (/^\[object \w+\]$/.test(errorString)) { -                errorString = JSON.stringify(error); -            } -        } catch (e) { -            errorString = `${error}`; -        } - -        let errorStack; -        try { -            errorStack = (typeof error.stack === 'string' ? error.stack.trimRight() : ''); -        } catch (e) { -            errorStack = ''; -        } - -        let errorData; -        try { -            errorData = error.data; -        } catch (e) { -            // NOP -        } - -        if (errorStack.startsWith(errorString)) { -            errorString = errorStack; -        } else if (errorStack.length > 0) { -            errorString += `\n${errorStack}`; -        } - -        let message = `${this._extensionName} has encountered a problem.`; -        message += `\nOriginating URL: ${context.url}\n`; -        message += errorString; -        if (typeof errorData !== 'undefined') { -            message += `\nData: ${JSON.stringify(errorData, null, 4)}`; -        } -        message += '\n\nIssues can be reported at https://github.com/FooSoft/yomichan/issues'; - -        switch (level) { -            case 'info': console.info(message); break; -            case 'debug': console.debug(message); break; -            case 'warn': console.warn(message); break; -            case 'error': console.error(message); break; -            default: console.log(message); break; -        } - -        this.trigger('log', {error, level, context}); -    } -      sendMessage(...args) {          try {              return chrome.runtime.sendMessage(...args); |