Many improvements
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
const overlay = document.createElement("section");
|
||||
overlay.className = "error-overlay";
|
||||
overlay.hidden = true;
|
||||
overlay.innerHTML = `
|
||||
<div class="error-overlay-header">
|
||||
<strong>JavaScript error</strong>
|
||||
<div class="error-overlay-actions">
|
||||
<button type="button" data-action="copy">Copy</button>
|
||||
<button type="button" data-action="dismiss" aria-label="Dismiss error">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
<pre></pre>
|
||||
`;
|
||||
|
||||
const messageNode = overlay.querySelector("pre");
|
||||
const copyButton = overlay.querySelector("[data-action='copy']");
|
||||
const dismissButton = overlay.querySelector("[data-action='dismiss']");
|
||||
|
||||
copyButton.addEventListener("click", async () => {
|
||||
await copyText(messageNode.textContent);
|
||||
showCopyStatus();
|
||||
});
|
||||
|
||||
dismissButton.addEventListener("click", () => {
|
||||
overlay.hidden = true;
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.body.append(overlay);
|
||||
});
|
||||
|
||||
window.addEventListener("error", (event) => {
|
||||
showError(formatErrorEvent(event));
|
||||
});
|
||||
|
||||
window.addEventListener("unhandledrejection", (event) => {
|
||||
showError(formatReason(event.reason));
|
||||
});
|
||||
|
||||
function showError(message) {
|
||||
messageNode.textContent = message;
|
||||
copyButton.textContent = "Copy";
|
||||
overlay.hidden = false;
|
||||
}
|
||||
|
||||
async function copyText(value) {
|
||||
if (navigator.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(value);
|
||||
return;
|
||||
}
|
||||
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.value = value;
|
||||
textArea.setAttribute("readonly", "");
|
||||
textArea.className = "error-overlay-copy-buffer";
|
||||
document.body.append(textArea);
|
||||
textArea.select();
|
||||
document.execCommand("copy");
|
||||
textArea.remove();
|
||||
}
|
||||
|
||||
function showCopyStatus() {
|
||||
copyButton.textContent = "Copied";
|
||||
|
||||
window.setTimeout(() => {
|
||||
copyButton.textContent = "Copy";
|
||||
}, 1400);
|
||||
}
|
||||
|
||||
function formatErrorEvent(event) {
|
||||
const location = [event.filename, event.lineno, event.colno].filter(Boolean).join(":");
|
||||
const detail = formatReason(event.error ?? event.message);
|
||||
return location ? `${detail}\n\n${location}` : detail;
|
||||
}
|
||||
|
||||
function formatReason(reason) {
|
||||
if (reason instanceof Error) {
|
||||
return reason.stack ?? `${reason.name}: ${reason.message}`;
|
||||
}
|
||||
|
||||
return String(reason);
|
||||
}
|
||||
Reference in New Issue
Block a user