aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/bg/css/settings.css17
-rw-r--r--ext/bg/js/request.js7
-rw-r--r--ext/bg/js/settings/anki.js26
-rw-r--r--ext/mixed/js/core.js10
4 files changed, 53 insertions, 7 deletions
diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css
index 63cead6b..815a88fa 100644
--- a/ext/bg/css/settings.css
+++ b/ext/bg/css/settings.css
@@ -187,6 +187,23 @@ input[type=checkbox].storage-button-checkbox {
margin: 0;
}
+.error-data-show-button {
+ display: inline-block;
+ margin-left: 0.5em;
+ cursor: pointer;
+}
+.error-data-show-button:after {
+ content: "\2026";
+ font-weight: bold;
+}
+
+.error-data-container {
+ margin-top: 0.25em;
+ font-family: 'Courier New', Courier, monospace;
+ white-space: pre;
+ overflow-x: auto;
+}
+
[data-show-for-browser],
[data-show-for-operating-system] {
display: none;
diff --git a/ext/bg/js/request.js b/ext/bg/js/request.js
index 778f933b..02eed6fb 100644
--- a/ext/bg/js/request.js
+++ b/ext/bg/js/request.js
@@ -36,8 +36,9 @@ async function requestJson(url, action, params) {
const responseText = await requestText(url, action, params);
try {
return JSON.parse(responseText);
- }
- catch (e) {
- throw new Error('Invalid response');
+ } catch (e) {
+ const error = new Error(`Invalid response (${e.message || e})`);
+ error.data = {url, action, params, responseText};
+ throw error;
}
}
diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js
index 5f7989b8..9adb2f2a 100644
--- a/ext/bg/js/settings/anki.js
+++ b/ext/bg/js/settings/anki.js
@@ -37,13 +37,35 @@ function _ankiSetError(error) {
if (error) {
node.hidden = false;
node.textContent = `${error}`;
- }
- else {
+ _ankiSetErrorData(node, error);
+ } else {
node.hidden = true;
node.textContent = '';
}
}
+function _ankiSetErrorData(node, error) {
+ const data = error.data;
+ let message = '';
+ if (typeof data !== 'undefined') {
+ message += `${JSON.stringify(data, null, 4)}\n\n`;
+ }
+ message += `${error.stack}`.trimRight();
+
+ const button = document.createElement('a');
+ button.className = 'error-data-show-button';
+
+ const content = document.createElement('div');
+ content.className = 'error-data-container';
+ content.textContent = message;
+ content.hidden = true;
+
+ button.addEventListener('click', () => content.hidden = !content.hidden, false);
+
+ node.appendChild(button);
+ node.appendChild(content);
+}
+
function _ankiSetDropdownOptions(dropdown, optionValues) {
const fragment = document.createDocumentFragment();
for (const optionValue of optionValues) {
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index 54e8a9d2..7fc01c94 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -56,7 +56,8 @@ function errorToJson(error) {
return {
name: error.name,
message: error.message,
- stack: error.stack
+ stack: error.stack,
+ data: error.data
};
}
@@ -64,6 +65,7 @@ function jsonToError(jsonError) {
const error = new Error(jsonError.message);
error.name = jsonError.name;
error.stack = jsonError.stack;
+ error.data = jsonError.data;
return error;
}
@@ -74,7 +76,11 @@ function logError(error, alert) {
const errorString = `${error.toString ? error.toString() : error}`;
const stack = `${error.stack}`.trimRight();
- errorMessage += (!stack.startsWith(errorString) ? `${errorString}\n${stack}` : `${stack}`);
+ 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';