Skip to content

Commit

Permalink
Detect and handle non-existing tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
fregante committed Jun 6, 2022
1 parent 9fad364 commit 7581246
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@
"p-retry": "^5.1.0",
"serialize-error": "^11.0.0",
"type-fest": "^2.12.1",
"webext-detect-page": "^4.0.1"
"webext-detect-page": "^4.0.1",
"webext-tools": "^1.1.0"
},
"devDependencies": {
"@parcel/config-webextension": "^2.4.0",
Expand Down
17 changes: 14 additions & 3 deletions source/sender.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pRetry from "p-retry";
import { isBackground } from "webext-detect-page";
import { doesTabExist } from "webext-tools";
import { deserializeError } from "serialize-error";

import {
Expand All @@ -22,9 +23,11 @@ import {
} from "./shared.js";
import { SetReturnType } from "type-fest";

export const errorNonExistingTarget =
const _errorNonExistingTarget =
"Could not establish connection. Receiving end does not exist.";

export const errorTabDoesntExist = "The tab doesn't exist";

function isMessengerResponse(response: unknown): response is MessengerResponse {
return isObject(response) && response["__webextMessenger"] === true;
}
Expand Down Expand Up @@ -81,12 +84,20 @@ async function manageMessage(
minTimeout: 100,
factor: 1.3,
maxRetryTime: 4000,
onFailedAttempt(error) {
async onFailedAttempt(error) {
if (
// Don't retry sending to the background page unless it really hasn't loaded yet
(target.page !== "background" && error instanceof MessengerError) ||
String(error.message).startsWith(errorNonExistingTarget)
String(error.message).startsWith(_errorNonExistingTarget)
) {
if (
browser.tabs &&
typeof target.tabId === "number" &&
!(await doesTabExist(target.tabId))
) {
throw new Error(errorTabDoesntExist);
}

debug(type, "will retry. Attempt", error.attemptNumber);
} else {
throw error;
Expand Down
16 changes: 15 additions & 1 deletion source/test/contentscript/api.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import test from "tape";
import { isBackground, isContentScript, isWebPage } from "webext-detect-page";
import { PageTarget, Sender, Target } from "../..";
import { errorTabDoesntExist, errorTargetClosedEarly } from "../../sender";
import { expectRejection, sleep, trackSettleTime } from "../helpers";
import * as backgroundContext from "../background/api";
import * as localContext from "../background/testingApi";
import { expectRejection } from "../helpers";
import * as contentScriptContext from "./api";
import {
getPageTitle,
setPageTitle,
Expand Down Expand Up @@ -220,6 +221,19 @@ async function init() {
await closeTab(tabId);
});

test("stops trying immediately if specific tab ID doesn't exist", async (t) => {
const request = getPageTitle({ tabId });
const durationPromise = trackSettleTime(request);

await expectRejection(t, request, new Error(errorTabDoesntExist));

const duration = await durationPromise;
t.ok(
duration < 100,
`It should take less than 100 ms (took ${duration}ms)`
);
});

test("retries until it times out", async (t) => {
const tabId = await openTab(
"https://fregante.github.io/pixiebrix-testing-ground/No-static-content-scripts"
Expand Down

0 comments on commit 7581246

Please sign in to comment.