From 8583aeb070d8c16f4645da40fa6e6f01819dd39a Mon Sep 17 00:00:00 2001 From: Federico Brigante Date: Mon, 6 Jun 2022 14:39:58 +0800 Subject: [PATCH] Handle closed tabs better --- package-lock.json | 68 ++++++++++++++++++++------------------ package.json | 2 +- src/background/executor.ts | 37 +++++++++++---------- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2ef5acb0eb..1f87b6a6bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -128,7 +128,7 @@ "webext-content-scripts": "^1.0.1", "webext-detect-page": "^4.0.1", "webext-dynamic-content-scripts": "^8.1.1", - "webext-messenger": "^0.18.2", + "webext-messenger": "^0.19.1", "webext-patterns": "^1.1.1", "webext-polyfill-kinda": "^0.10.0", "webext-tools": "^1.0.0", @@ -28862,9 +28862,9 @@ } }, "node_modules/obj-props": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.3.0.tgz", - "integrity": "sha512-k2Xkjx5wn6eC3537SWAXHzB6lkI81kS+icMKMkh4nG3w7shWG6MaWOBrNvhWVOszrtL5uxdfymQQfPUxwY+2eg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz", + "integrity": "sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -29440,11 +29440,11 @@ } }, "node_modules/p-retry": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.0.tgz", - "integrity": "sha512-zh8em2ciphCu4eZYzatLp4bTYkAhyi8PwMIOyQyh1b5bxunYNe6nwumHPkUBtvmEfIfnTYzhOq1+vWf46Qii+w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.1.tgz", + "integrity": "sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA==", "dependencies": { - "@types/retry": "^0.12.1", + "@types/retry": "0.12.1", "retry": "^0.13.1" }, "engines": { @@ -36547,14 +36547,15 @@ } }, "node_modules/webext-messenger": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/webext-messenger/-/webext-messenger-0.18.2.tgz", - "integrity": "sha512-2/MHxTYbwMpsADiHMTAuB08i8zR8CJw/pbXeILXRACB4WufRuhFWYOOSNbUiBLt1k7yGbDkBtRqHUfGXqZQCaA==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/webext-messenger/-/webext-messenger-0.19.1.tgz", + "integrity": "sha512-Z30zeSi7nSibErpNRXkw+otBBOG3Yz61qBUTbPMyk4l4+V6doYMd2kwXHLEOeeFKQFzvG1wLZp15ZLwEl0w4xw==", "dependencies": { - "p-retry": "^5.1.0", + "p-retry": "^5.1.1", "serialize-error": "^11.0.0", - "type-fest": "^2.12.1", - "webext-detect-page": "^4.0.1" + "type-fest": "^2.13.0", + "webext-detect-page": "^4.0.1", + "webext-tools": "^1.1.0" } }, "node_modules/webext-patterns": { @@ -36568,9 +36569,9 @@ "integrity": "sha512-Yz5WTwig5byFfMXgagtfaJkVU+RrnVqtL1hmvA+GIbpRaGKU1DIrFYHMUUFkeyFqxRSuhbOdLKzteXxCd6VNzA==" }, "node_modules/webext-tools": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/webext-tools/-/webext-tools-1.0.0.tgz", - "integrity": "sha512-VGU7dCsIoUO3d+aFCd9hX/7Mn3D/oNJKjc6r/0uVaY9YbwUpfdRY7nK8lFLlIjLP0qPbvhcHLV1IGE6vSUjo2w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webext-tools/-/webext-tools-1.1.0.tgz", + "integrity": "sha512-jgkEe2zU1uStOyFaQh66k6w6FleSoc7T+ePOdw36RJv53D5dkHwFVXzJ1UWsDvls45uZSAmDH5eBx7gpnN7dPA==", "dependencies": { "webext-content-scripts": "^1.0.1", "webext-detect-page": "^4.0.1", @@ -59445,9 +59446,9 @@ "dev": true }, "obj-props": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.3.0.tgz", - "integrity": "sha512-k2Xkjx5wn6eC3537SWAXHzB6lkI81kS+icMKMkh4nG3w7shWG6MaWOBrNvhWVOszrtL5uxdfymQQfPUxwY+2eg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz", + "integrity": "sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==", "dev": true }, "object-assign": { @@ -59863,11 +59864,11 @@ } }, "p-retry": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.0.tgz", - "integrity": "sha512-zh8em2ciphCu4eZYzatLp4bTYkAhyi8PwMIOyQyh1b5bxunYNe6nwumHPkUBtvmEfIfnTYzhOq1+vWf46Qii+w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.1.tgz", + "integrity": "sha512-i69WkEU5ZAL8mrmdmVviWwU+DN+IUF8f4sSJThoJ3z5A7Nn5iuO5ROX3Boye0u+uYQLOSfgFl7SuFZCjlAVbQA==", "requires": { - "@types/retry": "^0.12.1", + "@types/retry": "0.12.1", "retry": "^0.13.1" } }, @@ -65501,14 +65502,15 @@ } }, "webext-messenger": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/webext-messenger/-/webext-messenger-0.18.2.tgz", - "integrity": "sha512-2/MHxTYbwMpsADiHMTAuB08i8zR8CJw/pbXeILXRACB4WufRuhFWYOOSNbUiBLt1k7yGbDkBtRqHUfGXqZQCaA==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/webext-messenger/-/webext-messenger-0.19.1.tgz", + "integrity": "sha512-Z30zeSi7nSibErpNRXkw+otBBOG3Yz61qBUTbPMyk4l4+V6doYMd2kwXHLEOeeFKQFzvG1wLZp15ZLwEl0w4xw==", "requires": { - "p-retry": "^5.1.0", + "p-retry": "^5.1.1", "serialize-error": "^11.0.0", - "type-fest": "^2.12.1", - "webext-detect-page": "^4.0.1" + "type-fest": "^2.13.0", + "webext-detect-page": "^4.0.1", + "webext-tools": "^1.1.0" } }, "webext-patterns": { @@ -65522,9 +65524,9 @@ "integrity": "sha512-Yz5WTwig5byFfMXgagtfaJkVU+RrnVqtL1hmvA+GIbpRaGKU1DIrFYHMUUFkeyFqxRSuhbOdLKzteXxCd6VNzA==" }, "webext-tools": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/webext-tools/-/webext-tools-1.0.0.tgz", - "integrity": "sha512-VGU7dCsIoUO3d+aFCd9hX/7Mn3D/oNJKjc6r/0uVaY9YbwUpfdRY7nK8lFLlIjLP0qPbvhcHLV1IGE6vSUjo2w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webext-tools/-/webext-tools-1.1.0.tgz", + "integrity": "sha512-jgkEe2zU1uStOyFaQh66k6w6FleSoc7T+ePOdw36RJv53D5dkHwFVXzJ1UWsDvls45uZSAmDH5eBx7gpnN7dPA==", "requires": { "webext-content-scripts": "^1.0.1", "webext-detect-page": "^4.0.1", diff --git a/package.json b/package.json index ff511a1006..05bddeb25a 100644 --- a/package.json +++ b/package.json @@ -149,7 +149,7 @@ "webext-content-scripts": "^1.0.1", "webext-detect-page": "^4.0.1", "webext-dynamic-content-scripts": "^8.1.1", - "webext-messenger": "^0.18.2", + "webext-messenger": "^0.19.1", "webext-patterns": "^1.1.1", "webext-polyfill-kinda": "^0.10.0", "webext-tools": "^1.0.0", diff --git a/src/background/executor.ts b/src/background/executor.ts index 92bfc334f1..f8b33105b4 100644 --- a/src/background/executor.ts +++ b/src/background/executor.ts @@ -20,42 +20,45 @@ import { expectContext } from "@/utils/expectContext"; import { asyncForEach } from "@/utils"; import { getLinkedApiClient } from "@/services/apiClient"; import { JsonObject } from "type-fest"; -import { MessengerMeta } from "webext-messenger"; +import { + MessengerMeta, + errorTargetClosedEarly, + errorTabDoesntExist, +} from "webext-messenger"; import { runBrick } from "@/contentScript/messenger/api"; import { Target } from "@/types"; import { RemoteExecutionError } from "@/blocks/errors"; import pDefer from "p-defer"; import { canAccessTab } from "webext-tools"; -import { onTabClose } from "@/chrome"; +import { getErrorMessage } from "@/errors/errorHelpers"; // eslint-disable-next-line import/no-restricted-paths -- Type only import type { RunBlock } from "@/contentScript/runBlockTypes"; import { BusinessError } from "@/errors/businessErrors"; type TabId = number; -// Used to determine which promise was resolved in a race -const TYPE_WAS_CLOSED = Symbol("Tab was closed"); - const tabToOpener = new Map(); const tabToTarget = new Map(); // TODO: One tab could have multiple targets, but `tabToTarget` currenly only supports one at a time async function safelyRunBrick({ tabId }: { tabId: number }, request: RunBlock) { - if (!(await canAccessTab(tabId))) { - throw new BusinessError("PixieBrix doesn't have access to the tab"); - } + try { + return await runBrick({ tabId }, request); + } catch (error) { + const errorMessage = getErrorMessage(error); + + // Repackage tab-lifecycle-related errors as BusinessErrors + if ([errorTargetClosedEarly, errorTabDoesntExist].includes(errorMessage)) { + throw new BusinessError(errorMessage); + } - const result = await Promise.race([ - // If https://github.com/pixiebrix/webext-messenger/issues/67 is resolved, we don't need the listener - onTabClose(tabId).then(() => TYPE_WAS_CLOSED), - runBrick({ tabId }, request), - ]); + // This must follow the tab existence checks or else it returns false even if the tab simply doesn't exist + if (!(await canAccessTab(tabId))) { + throw new BusinessError("PixieBrix doesn't have access to the tab"); + } - if (result === TYPE_WAS_CLOSED) { - throw new BusinessError("The tab was closed"); + throw error; } - - return result; } export async function waitForTargetByUrl(url: string): Promise {