Context
apps/loopover-miner-extension/content.js:42-54 (loadOpportunityBadge) calls await chrome.runtime.sendMessage(...) with no try/catch. Every other message/async-boundary call site in this extension handles failure explicitly: background.js:19-21 (.then(...).catch((error) => sendResponse({ ok: false, ... }))), options.js:78-94 (form submit wraps everything in try/catch), and options.js:99-113 (syncNow wraps its own sendMessage in try/catch). If sendMessage rejects — a real MV3 failure mode (service worker asleep/restarting, "Extension context invalidated") — it's an unhandled rejection: the badge <aside> stays in the DOM permanently hidden with zero user-visible feedback, unlike the graceful container.remove() this same function already uses for its other failure paths.
Requirements
- Wrap the
chrome.runtime.sendMessage(...) call in loadOpportunityBadge in a try/catch, and on failure, call the same container.remove() cleanup this function already uses for its other failure paths (don't invent a new failure UX).
- Do not change
background.js's or options.js's existing error handling — they're already correct.
Test Coverage Requirements
Match this extension's existing test conventions (test/*.test.ts); add a regression test simulating a rejected sendMessage and confirming the badge container is cleanly removed instead of causing an unhandled rejection.
Deliverables
Expected Outcome
A sendMessage failure in the content script no longer produces an unhandled rejection or a permanently-hidden orphan DOM element.
Links & Resources
apps/loopover-miner-extension/content.js:42-54
apps/loopover-miner-extension/background.js:19-21, options.js:78-94,99-113 (existing error-handling pattern to match)
Context
apps/loopover-miner-extension/content.js:42-54(loadOpportunityBadge) callsawait chrome.runtime.sendMessage(...)with notry/catch. Every other message/async-boundary call site in this extension handles failure explicitly:background.js:19-21(.then(...).catch((error) => sendResponse({ ok: false, ... }))),options.js:78-94(form submit wraps everything intry/catch), andoptions.js:99-113(syncNowwraps its ownsendMessageintry/catch). IfsendMessagerejects — a real MV3 failure mode (service worker asleep/restarting, "Extension context invalidated") — it's an unhandled rejection: the badge<aside>stays in the DOM permanently hidden with zero user-visible feedback, unlike the gracefulcontainer.remove()this same function already uses for its other failure paths.Requirements
chrome.runtime.sendMessage(...)call inloadOpportunityBadgein atry/catch, and on failure, call the samecontainer.remove()cleanup this function already uses for its other failure paths (don't invent a new failure UX).background.js's oroptions.js's existing error handling — they're already correct.Test Coverage Requirements
Match this extension's existing test conventions (
test/*.test.ts); add a regression test simulating a rejectedsendMessageand confirming the badge container is cleanly removed instead of causing an unhandled rejection.Deliverables
loadOpportunityBadgehandles a rejectedsendMessagethe same way it handles its other failure paths.Expected Outcome
A
sendMessagefailure in the content script no longer produces an unhandled rejection or a permanently-hidden orphan DOM element.Links & Resources
apps/loopover-miner-extension/content.js:42-54apps/loopover-miner-extension/background.js:19-21,options.js:78-94,99-113(existing error-handling pattern to match)