summaryrefslogtreecommitdiff
path: root/ext/mixed/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-04-26 16:55:25 -0400
committerGitHub <noreply@github.com>2020-04-26 16:55:25 -0400
commit5b96559df819f496b39acb75c679f6b3d8c8e65d (patch)
tree95af8543c642f4ddc30982526e022967aac49742 /ext/mixed/js
parentca033a87a0d302151b430acfdf9d480514c14aed (diff)
Error logging refactoring (#454)
* Create new logging methods on yomichan object * Use new yomichan.logError instead of global logError * Remove old logError * Handle unhandledrejection events * Add addEventListener stub * Update log function * Update error conversion to support more types * Add log event * Add API log function * Log errors to the backend * Make error/warning logs update the badge * Clear log error indicator on extension button click * Log correct URL on the background page * Fix incorrect error conversion * Remove unhandledrejection handling Firefox doesn't support it properly. * Remove unused argument type from log function * Improve function name * Change console.warn to yomichan.logWarning * Move log forwarding initialization into main scripts
Diffstat (limited to 'ext/mixed/js')
-rw-r--r--ext/mixed/js/api.js22
-rw-r--r--ext/mixed/js/core.js112
-rw-r--r--ext/mixed/js/text-scanner.js2
3 files changed, 109 insertions, 27 deletions
diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js
index 52f41646..afd68aa2 100644
--- a/ext/mixed/js/api.js
+++ b/ext/mixed/js/api.js
@@ -144,6 +144,14 @@ function apiGetMedia(targets) {
return _apiInvoke('getMedia', {targets});
}
+function apiLog(error, level, context) {
+ return _apiInvoke('log', {error, level, context});
+}
+
+function apiLogIndicatorClear() {
+ return _apiInvoke('logIndicatorClear');
+}
+
function _apiInvoke(action, params={}) {
const data = {action, params};
return new Promise((resolve, reject) => {
@@ -171,3 +179,17 @@ function _apiInvoke(action, params={}) {
function _apiCheckLastError() {
// NOP
}
+
+let _apiForwardLogsToBackendEnabled = false;
+function apiForwardLogsToBackend() {
+ if (_apiForwardLogsToBackendEnabled) { return; }
+ _apiForwardLogsToBackendEnabled = true;
+
+ yomichan.on('log', async ({error, level, context}) => {
+ try {
+ await apiLog(errorToJson(error), level, context);
+ } catch (e) {
+ // NOP
+ }
+ });
+}
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index 6a3298fc..fbe9943a 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -52,15 +52,28 @@ if (EXTENSION_IS_BROWSER_EDGE) {
*/
function errorToJson(error) {
+ try {
+ if (isObject(error)) {
+ return {
+ name: error.name,
+ message: error.message,
+ stack: error.stack,
+ data: error.data
+ };
+ }
+ } catch (e) {
+ // NOP
+ }
return {
- name: error.name,
- message: error.message,
- stack: error.stack,
- data: error.data
+ value: error,
+ hasValue: true
};
}
function jsonToError(jsonError) {
+ if (jsonError.hasValue) {
+ return jsonError.value;
+ }
const error = new Error(jsonError.message);
error.name = jsonError.name;
error.stack = jsonError.stack;
@@ -68,28 +81,6 @@ function jsonToError(jsonError) {
return error;
}
-function logError(error, alert) {
- const manifest = chrome.runtime.getManifest();
- let errorMessage = `${manifest.name} v${manifest.version} has encountered an error.\n`;
- errorMessage += `Originating URL: ${window.location.href}\n`;
-
- const errorString = `${error.toString ? error.toString() : error}`;
- const stack = `${error.stack}`.trimRight();
- if (!stack.startsWith(errorString)) { errorMessage += `${errorString}\n`; }
- errorMessage += stack;
-
- const data = error.data;
- if (typeof data !== 'undefined') { errorMessage += `\nData: ${JSON.stringify(data, null, 4)}`; }
-
- errorMessage += '\n\nIssues can be reported at https://github.com/FooSoft/yomichan/issues';
-
- console.error(errorMessage);
-
- if (alert) {
- window.alert(`${errorString}\n\nCheck the developer console for more details.`);
- }
-}
-
/*
* Common helpers
@@ -361,8 +352,77 @@ const yomichan = (() => {
});
}
+ 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}`;
+ }
+
+ const manifest = chrome.runtime.getManifest();
+ let message = `${manifest.name} v${manifest.version} 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});
+ }
+
// Private
+ _getLogContext() {
+ return {
+ url: window.location.href
+ };
+ }
+
_onMessage({action, params}, sender, callback) {
const handler = this._messageHandlers.get(action);
if (typeof handler !== 'function') { return false; }
diff --git a/ext/mixed/js/text-scanner.js b/ext/mixed/js/text-scanner.js
index 0cd12cd7..1c32714b 100644
--- a/ext/mixed/js/text-scanner.js
+++ b/ext/mixed/js/text-scanner.js
@@ -201,7 +201,7 @@ class TextScanner {
}
onError(error) {
- logError(error, false);
+ yomichan.logError(error);
}
async scanTimerWait() {