diff options
Diffstat (limited to 'browser/extensions/screenshots/background/senderror.js')
-rw-r--r-- | browser/extensions/screenshots/background/senderror.js | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/browser/extensions/screenshots/background/senderror.js b/browser/extensions/screenshots/background/senderror.js new file mode 100644 index 0000000000..cad0fc52ce --- /dev/null +++ b/browser/extensions/screenshots/background/senderror.js @@ -0,0 +1,144 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* globals startBackground, analytics, communication, catcher, log, browser, getStrings */ + +"use strict"; + +this.senderror = (function() { + const exports = {}; + + // Do not show an error more than every ERROR_TIME_LIMIT milliseconds: + const ERROR_TIME_LIMIT = 3000; + + const messages = { + REQUEST_ERROR: { + titleKey: "screenshots-request-error-title", + infoKey: "screenshots-request-error-details", + }, + CONNECTION_ERROR: { + titleKey: "screenshots-connection-error-title", + infoKey: "screenshots-connection-error-details", + }, + LOGIN_ERROR: { + titleKey: "screenshots-request-error-title", + infoKey: "screenshots-login-error-details", + }, + LOGIN_CONNECTION_ERROR: { + titleKey: "screenshots-connection-error-title", + infoKey: "screenshots-connection-error-details", + }, + UNSHOOTABLE_PAGE: { + titleKey: "screenshots-unshootable-page-error-title", + infoKey: "screenshots-unshootable-page-error-details", + }, + EMPTY_SELECTION: { + titleKey: "screenshots-empty-selection-error-title", + }, + PRIVATE_WINDOW: { + titleKey: "screenshots-private-window-error-title", + infoKey: "screenshots-private-window-error-details", + }, + generic: { + titleKey: "screenshots-generic-error-title", + infoKey: "screenshots-generic-error-details", + showMessage: true, + }, + }; + + communication.register("reportError", (sender, error) => { + catcher.unhandled(error); + }); + + let lastErrorTime; + + exports.showError = async function(error) { + if (lastErrorTime && Date.now() - lastErrorTime < ERROR_TIME_LIMIT) { + return; + } + lastErrorTime = Date.now(); + const id = crypto.randomUUID(); + let popupMessage = error.popupMessage || "generic"; + if (!messages[popupMessage]) { + popupMessage = "generic"; + } + + let item = messages[popupMessage]; + if (!("title" in item)) { + let keys = [{ id: item.titleKey }]; + if ("infoKey" in item) { + keys.push({ id: item.infoKey }); + } + + [item.title, item.info] = await getStrings(keys); + } + + let title = item.title; + let message = item.info || ""; + const showMessage = item.showMessage; + if (error.message && showMessage) { + if (message) { + message += "\n" + error.message; + } else { + message = error.message; + } + } + if (Date.now() - startBackground.startTime > 5 * 1000) { + browser.notifications.create(id, { + type: "basic", + // FIXME: need iconUrl for an image, see #2239 + title, + message, + }); + } + }; + + exports.reportError = function(e) { + if (!analytics.isTelemetryEnabled()) { + log.error("Telemetry disabled. Not sending critical error:", e); + return; + } + const exception = new Error(e.message); + exception.stack = e.multilineStack || e.stack || undefined; + + // To improve Sentry reporting & grouping, replace the + // moz-extension://$uuid base URL with a generic resource:// URL. + if (exception.stack) { + exception.stack = exception.stack.replace( + /moz-extension:\/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g, + "resource://screenshots-addon" + ); + } + const rest = {}; + for (const attr in e) { + if ( + ![ + "name", + "message", + "stack", + "multilineStack", + "popupMessage", + "version", + "sentryPublicDSN", + "help", + "fromMakeError", + ].includes(attr) + ) { + rest[attr] = e[attr]; + } + } + rest.stack = exception.stack; + }; + + catcher.registerHandler(errorObj => { + if (!errorObj.noPopup) { + exports.showError(errorObj); + } + if (!errorObj.noReport) { + exports.reportError(errorObj); + } + }); + + return exports; +})(); |