fix(extension): detect browser error pages earlier
Testing / test (push) Successful in 26s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 27s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 20s
Package Extension / package-extension (push) Successful in 28s
Build & Publish Package / publish (push) Successful in 31s

- Add shared browser error URL detection for Chrome, Edge, Brave, and Firefox-style about:error pages.
- Short-circuit read-only DOM and HTML commands with safe fallbacks when tabs are already on browser error pages.
- Fail navigation waits, DOM waits, polling, and URL watches with clearer error-page messages.
- Bump package and extension version to 0.9.8 and extend regression coverage for cross-browser error-page handling.
This commit is contained in:
2026-05-14 13:54:21 +02:00
parent f79ff0e3c2
commit eaa1469143
8 changed files with 61 additions and 15 deletions
+10 -5
View File
@@ -1,5 +1,5 @@
// @ts-nocheck
import { executeScript, getActiveTab, getAliases, isScriptableUrl, resolveTabForDirectAction, tabInfo } from '../core';
import { executeScript, getActiveTab, getAliases, isBrowserErrorUrl, isErrorPageScriptError, isScriptableUrl, resolveTabForDirectAction, tabInfo } from '../core';
export async function tabsList() {
const windows = await chrome.windows.getAll({ populate: true });
const aliases = await getAliases();
@@ -102,8 +102,12 @@ export async function tabsQuery({ search }) {
export async function tabsHtml({ tabId }) {
for (let i = 0; i < 3; i++) {
const tab = tabId ? await chrome.tabs.get(tabId) : await getActiveTab();
if (!isScriptableUrl(tab.url || tab.pendingUrl || "")) {
throw new Error(`Cannot get HTML of ${tab.url || tab.pendingUrl} — navigate to a regular web page first`);
const tabUrl = tab.url || tab.pendingUrl || "";
if (isBrowserErrorUrl(tabUrl)) {
return "";
}
if (!isScriptableUrl(tabUrl)) {
throw new Error(`Cannot get HTML of ${tabUrl} — navigate to a regular web page first`);
}
try {
const results = await executeScript({
@@ -112,7 +116,8 @@ export async function tabsHtml({ tabId }) {
});
return results[0]?.result || "";
} catch (e) {
const transient = e.message && (e.message.includes("Frame with ID") || e.message.includes("No tab with id")) && !e.message.includes("error page");
if (isErrorPageScriptError(e)) return "";
const transient = e.message && (e.message.includes("Frame with ID") || e.message.includes("No tab with id"));
if (i < 2 && transient) {
await new Promise(r => setTimeout(r, 300));
continue;
@@ -205,7 +210,7 @@ export async function tabsWatchUrl({ pattern, timeout = 30000, tabId } = {}) {
lastUrl = t.url || t.pendingUrl || "";
lastStatus = t.status || "unknown";
if (matches(t.pendingUrl || "") || matches(t.url || "")) return tabInfo(t);
if ((t.url || "").startsWith("chrome-error://")) {
if (isBrowserErrorUrl(t.url || "")) {
throw new Error(`Tab ${tab.id} is showing an error page while waiting for URL to match '${pattern}'`);
}
await new Promise(r => setTimeout(r, 200));