Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DevTools] improve error handling in extension #26068

Merged
merged 3 commits into from
Feb 7, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 44 additions & 19 deletions packages/react-devtools-extensions/src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,31 @@ if (!IS_FIREFOX) {
// It's critical since it allows us to directly run scripts on the "main" world on the page
// "document_start" allows it to run before the page's scripts
// so the hook can be detected by react reconciler
chrome.scripting.registerContentScripts([
{
id: 'hook',
matches: ['<all_urls>'],
js: ['build/installHook.js'],
runAt: 'document_start',
world: chrome.scripting.ExecutionWorld.MAIN,
},
{
id: 'renderer',
matches: ['<all_urls>'],
js: ['build/renderer.js'],
runAt: 'document_start',
world: chrome.scripting.ExecutionWorld.MAIN,
chrome.scripting.registerContentScripts(
[
{
id: 'hook',
matches: ['<all_urls>'],
js: ['build/installHook.js'],
runAt: 'document_start',
world: chrome.scripting.ExecutionWorld.MAIN,
},
{
id: 'renderer',
matches: ['<all_urls>'],
js: ['build/renderer.js'],
runAt: 'document_start',
world: chrome.scripting.ExecutionWorld.MAIN,
},
],
function() {
// When the content scripts are already registered, an error will be thrown.
// It happens when the service worker process is incorrectly duplicated.
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
}
},
]);
);
}

chrome.runtime.onConnect.addListener(function(port) {
Expand All @@ -51,7 +60,7 @@ chrome.runtime.onConnect.addListener(function(port) {
ports[tab][name] = port;

if (ports[tab].devtools && ports[tab]['content-script']) {
doublePipe(ports[tab].devtools, ports[tab]['content-script']);
doublePipe(ports[tab].devtools, ports[tab]['content-script'], tab);
}
});

Expand All @@ -70,20 +79,36 @@ function installProxy(tabId: number) {
}
}

function doublePipe(one, two) {
function doublePipe(one, two, tabId) {
one.onMessage.addListener(lOne);
function lOne(message) {
two.postMessage(message);
try {
two.postMessage(message);
} catch (e) {
if (__DEV__) {
console.log(`Broken pipe ${tabId}: `, e);
}
shutdown();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the postMessage fail because of a JS exception? I'm not sure if it will happen. I think if we shutdown here not during a page load, the devtools would stop working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a JS exception. It's a service worker exception when postMessage is fired on a tab that's offloaded. The error message looks like this:
image

It's weird that the listener was not removed since we already have one.onDisconnect.addListener(shutdown). Maybe Chrome doesn't treat reload as disconnect anymore?

}
}
two.onMessage.addListener(lTwo);
function lTwo(message) {
one.postMessage(message);
try {
one.postMessage(message);
} catch (e) {
if (__DEV__) {
console.log(`Broken pipe ${tabId}: `, e);
}
shutdown();
}
}
function shutdown() {
one.onMessage.removeListener(lOne);
two.onMessage.removeListener(lTwo);
one.disconnect();
two.disconnect();
// clean up so that we can rebuild the double pipe if the page is reloaded
ports[tabId] = null;
}
one.onDisconnect.addListener(shutdown);
two.onDisconnect.addListener(shutdown);
Expand Down