diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 6d979136c..6fbdc741f 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -4,6 +4,7 @@ import ObjectMultiplex from 'obj-multiplex'; import browser from 'webextension-polyfill'; import PortStream from 'extension-port-stream'; import { obj as createThoughStream } from 'through2'; +import log from 'loglevel'; import { EXTENSION_MESSAGES, MESSAGE_TYPE } from '../../shared/constants/app'; import { checkForLastError } from '../../shared/modules/browser-runtime.utils'; @@ -85,6 +86,9 @@ function injectScript(content) { * SERVICE WORKER LOGIC */ +const EXTENSION_CONTEXT_INVALIDATED_CHROMIUM_ERROR = + 'Extension context invalidated.'; + const WORKER_KEEP_ALIVE_INTERVAL = 1000; const WORKER_KEEP_ALIVE_MESSAGE = 'WORKER_KEEP_ALIVE_MESSAGE'; const TIME_45_MIN_IN_MS = 45 * 60 * 1000; @@ -103,6 +107,24 @@ const IGNORE_INIT_METHODS_FOR_KEEP_ALIVE = [ let keepAliveInterval; let keepAliveTimer; +/** + * Sending a message to the extension to receive will keep the service worker alive. + * + * If the extension is unloaded or reloaded during a session and the user attempts to send a + * message to the extension, an "Extension context invalidated." error will be thrown from + * chromium browsers. When this happens, prompt the user to reload the extension. Note: Handling + * this error is not supported in Firefox here. + */ +const sendMessageWorkerKeepAlive = () => { + browser.runtime + .sendMessage({ name: WORKER_KEEP_ALIVE_MESSAGE }) + .catch((e) => { + e.message === EXTENSION_CONTEXT_INVALIDATED_CHROMIUM_ERROR + ? log.error(`Please refresh the page. MetaMask: ${e}`) + : log.error(`MetaMask: ${e}`); + }); +}; + /** * Running this method will ensure the service worker is kept alive for 45 minutes. * The first message is sent immediately and subsequent messages are sent at an @@ -117,11 +139,11 @@ const runWorkerKeepAliveInterval = () => { clearInterval(keepAliveInterval); - browser.runtime.sendMessage({ name: WORKER_KEEP_ALIVE_MESSAGE }); + sendMessageWorkerKeepAlive(); keepAliveInterval = setInterval(() => { if (browser.runtime.id) { - browser.runtime.sendMessage({ name: WORKER_KEEP_ALIVE_MESSAGE }); + sendMessageWorkerKeepAlive(); } }, WORKER_KEEP_ALIVE_INTERVAL); };