[mv3] Share console error in troubleshooting information

This shoould help investigating issues, especially with mobile
devices, where the browser dev tools console is not available.
This commit is contained in:
Raymond Hill 2025-08-11 17:53:59 -04:00
parent a1a5f3690f
commit 28ea00fd11
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
10 changed files with 126 additions and 60 deletions

View file

@ -79,6 +79,7 @@ import {
getMatchedRules,
isSideloaded,
toggleDeveloperMode,
ubolErr,
ubolLog,
} from './debug.js';
@ -90,6 +91,7 @@ import {
} from './config.js';
import { dnr } from './ext-compat.js';
import { getTroubleshootingInfo } from './troubleshooting.js';
import { registerInjectables } from './scripting-manager.js';
import { toggleToolbarIcon } from './action.js';
@ -189,7 +191,7 @@ function onMessage(request, sender, callback) {
origin: 'USER',
target: { tabId, frameIds: [ frameId ] },
}).catch(reason => {
console.log(reason);
ubolErr(reason);
});
return false;
}
@ -201,7 +203,7 @@ function onMessage(request, sender, callback) {
origin: 'USER',
target: { tabId, frameIds: [ frameId ] },
}).catch(reason => {
console.log(reason);
ubolErr(reason);
});
return false;
}
@ -240,7 +242,7 @@ function onMessage(request, sender, callback) {
target: { tabId, frameIds: [ frameId ] },
injectImmediately: true,
}).catch(reason => {
console.log(reason);
ubolErr(reason);
}).then(( ) => {
callback();
});
@ -271,8 +273,9 @@ function onMessage(request, sender, callback) {
return registerInjectables();
}).then(( ) => {
callback(result);
broadcastMessage({ enabledRulesets: result.enabledRulesets });
});
}).finally(( ) => {
broadcastMessage({ enabledRulesets: rulesetConfig.enabledRulesets });
});
return true;
}
@ -506,6 +509,12 @@ function onMessage(request, sender, callback) {
});
return true;
case 'getTroubleshootingInfo':
getTroubleshootingInfo(request.siteMode).then(info => {
callback(info);
});
return true;
default:
break;
}
@ -639,7 +648,7 @@ const isFullyInitialized = start().then(( ) => {
localRemove('goodStart');
return false;
}).catch(reason => {
console.trace(reason);
ubolErr(reason);
if ( process.wakeupRun ) { return; }
return localRead('goodStart').then(goodStart => {
if ( goodStart === false ) {

View file

@ -24,11 +24,10 @@ import {
localRead,
localRemove,
localWrite,
runtime,
sendMessage,
} from './ext.js';
import { getTroubleshootingInfo } from './troubleshooting.js';
import { runtime } from './ext.js';
/******************************************************************************/
{
@ -53,9 +52,14 @@ localRead('dashboard.activePane').then(pane => {
dom.body.dataset.pane = pane;
});
getTroubleshootingInfo().then(config => {
qs$('[data-i18n="supportS5H"] + pre').textContent = config;
// Update troubleshooting on-demand
const tsinfoObserver = new IntersectionObserver(entries => {
if ( entries.every(a => a.isIntersecting === false) ) { return; }
sendMessage({ what: 'getTroubleshootingInfo' }).then(config => {
qs$('[data-i18n="supportS5H"] + pre').textContent = config;
});
});
tsinfoObserver.observe(qs$('[data-i18n="supportS5H"] + pre'));
/******************************************************************************/

View file

@ -19,26 +19,89 @@
Home: https://github.com/gorhill/uBlock
*/
import { dnr, normalizeDNRRules } from './ext-compat.js';
import { browser } from './ext.js';
import {
dnr,
normalizeDNRRules,
webext,
} from './ext-compat.js';
import {
sessionRead,
sessionWrite,
} from './ext.js';
/******************************************************************************/
const isModern = dnr.onRuleMatchedDebug instanceof Object;
export const isSideloaded = (( ) => {
const { permissions } = browser.runtime.getManifest();
const { permissions } = webext.runtime.getManifest();
return permissions?.includes('declarativeNetRequestFeedback') ?? false;
})();
/******************************************************************************/
const CONSOLE_MAX_LINES = 32;
const consoleOutput = [];
let consoleWritePtr = 0;
sessionRead('console').then(before => {
if ( Array.isArray(before) === false ) { return; }
const current = getConsoleOutput();
const merged = [ ...before, ...current ].slice(-CONSOLE_MAX_LINES);
for ( let i = 0; i < merged.length; i++ ) {
consoleOutput[i] = merged[i];
}
consoleWritePtr = merged.length % CONSOLE_MAX_LINES;
});
const consoleAdd = (...args) => {
if ( args.length === 0 ) { return; }
const now = new Date();
const time = [
`${now.getUTCMonth()+1}`.padStart(2, '0'),
`${now.getUTCDate()}`.padStart(2, '0'),
'.',
`${now.getUTCHours()}`.padStart(2, '0'),
`${now.getUTCMinutes()}`.padStart(2, '0'),
].join('');
for ( let i = 0; i < args.length; i++ ) {
const s = `[${time}]${args[i]}`;
if ( Boolean(s) === false ) { continue; }
consoleOutput[consoleWritePtr++] = s;
consoleWritePtr %= CONSOLE_MAX_LINES;
}
sessionWrite('console', getConsoleOutput());
}
export const ubolLog = (...args) => {
// Do not pollute dev console in stable releases.
if ( isSideloaded !== true ) { return; }
console.info('[uBOL]', ...args);
};
export const ubolErr = (...args) => {
if ( Array.isArray(args) === false ) { return; }
if ( globalThis.ServiceWorkerGlobalScope ) {
consoleAdd(...args);
}
// Do not pollute dev console in stable releases.
if ( isSideloaded !== true ) { return; }
console.error('[uBOL]', ...args);
};
export const getConsoleOutput = ( ) => {
return [
...consoleOutput.slice(consoleWritePtr),
...consoleOutput.slice(0, consoleWritePtr),
].reduce((acc, val) => {
if ( val !== acc.at(-1) ) {
acc.push(val);
}
return acc;
}, []);
};
/******************************************************************************/
const rulesets = new Map();

View file

@ -19,13 +19,15 @@
Home: https://github.com/gorhill/uBlock
*/
import { ubolErr } from './debug.js';
/******************************************************************************/
function fetchJSON(path) {
return fetch(`${path}.json`).then(response =>
response.json()
).catch(reason => {
console.info(reason);
ubolErr(reason);
});
}

View file

@ -34,6 +34,8 @@ import {
subtractHostnameIters,
} from './utils.js';
import { ubolErr } from './debug.js';
/******************************************************************************/
export async function selectorsFromCustomFilters(hostname) {
@ -79,7 +81,7 @@ export function startCustomFilters(tabId, frameId) {
target: { tabId, frameIds: [ frameId ] },
injectImmediately: true,
}).catch(reason => {
console.log(reason);
ubolErr(reason);
})
}
@ -89,7 +91,7 @@ export function terminateCustomFilters(tabId, frameId) {
target: { tabId, frameIds: [ frameId ] },
injectImmediately: true,
}).catch(reason => {
console.log(reason);
ubolErr(reason);
})
}
@ -107,7 +109,7 @@ export async function injectCustomFilters(tabId, frameId, hostname) {
origin: 'USER',
target: { tabId, frameIds: [ frameId ] },
}).catch(reason => {
console.log(reason);
ubolErr(reason);
})
);
}
@ -119,7 +121,7 @@ export async function injectCustomFilters(tabId, frameId, hostname) {
target: { tabId, frameIds: [ frameId ] },
injectImmediately: true,
}).catch(reason => {
console.log(reason);
ubolErr(reason);
})
);
}

View file

@ -20,7 +20,6 @@
*/
import { dom, qs$ } from './dom.js';
import { getTroubleshootingInfo } from './troubleshooting.js';
import { sendMessage } from './ext.js';
/******************************************************************************/
@ -93,7 +92,10 @@ async function reportSpecificFilterIssue() {
/******************************************************************************/
getTroubleshootingInfo(reportedPage.mode).then(config => {
sendMessage({
what: 'getTroubleshootingInfo',
siteMode: reportedPage.mode,
}).then(config => {
qs$('[data-i18n="supportS5H"] + pre').textContent = config;
dom.on('[data-url]', 'click', ev => {

View file

@ -36,7 +36,7 @@ import { fetchJSON } from './fetch.js';
import { getAdminRulesets } from './admin.js';
import { hasBroadHostPermissions } from './utils.js';
import { rulesFromText } from './dnr-parser.js';
import { ubolLog } from './debug.js';
import { ubolErr, ubolLog } from './debug.js';
/******************************************************************************/
@ -318,7 +318,7 @@ async function updateDynamicRules() {
ubolLog(`Add ${addRules.length} dynamic DNR rules`);
}
} catch(reason) {
console.error(`updateDynamicRules() / ${reason}`);
ubolErr(`updateDynamicRules() / ${reason}`);
response.error = `${reason}`;
}
@ -472,7 +472,7 @@ async function updateSessionRules() {
ubolLog(`Add ${addRules.length} session DNR rules`);
}
} catch(reason) {
console.error(`updateSessionRules() / ${reason}`);
ubolErr(`updateSessionRules() / ${reason}`);
response.error = `${reason}`;
}
return response;
@ -667,7 +667,7 @@ async function enableRulesets(ids) {
enableRulesetIds,
disableRulesetIds,
}).catch(reason => {
ubolLog(reason);
ubolErr(reason);
response.error = `${reason}`;
});
@ -684,7 +684,7 @@ async function enableRulesets(ids) {
ubolLog(`Available static rule count: ${count}`);
response.staticRuleCount = count;
}).catch(reason => {
ubolLog(reason);
ubolErr(reason);
});
return response;
@ -781,7 +781,7 @@ async function updateUserRules() {
out.added = addRules.length;
out.removed = removeRuleIds.length;
} catch(reason) {
console.info(`updateUserRules() / ${reason}`);
ubolErr(`updateUserRules() / ${reason}`);
out.errors.push(`${reason}`);
} finally {
const userRules = await getEffectiveUserRules();

View file

@ -21,18 +21,14 @@
import * as ut from './utils.js';
import {
browser,
localRemove,
localWrite,
} from './ext.js';
import { browser, localRemove } from './ext.js';
import { ubolErr, ubolLog } from './debug.js';
import { fetchJSON } from './fetch.js';
import { getEnabledRulesetsDetails } from './ruleset-manager.js';
import { getFilteringModeDetails } from './mode-manager.js';
import { registerCustomFilters } from './filter-manager.js';
import { registerToolbarIconToggler } from './action.js';
import { ubolLog } from './debug.js';
/******************************************************************************/
@ -555,8 +551,7 @@ async function registerInjectables() {
await browser.scripting.unregisterContentScripts({ ids: toRemove });
localRemove('$scripting.unregisterContentScripts');
} catch(reason) {
localWrite('$scripting.unregisterContentScripts', `${reason}`);
console.info(reason);
ubolErr(reason);
}
}
@ -566,8 +561,7 @@ async function registerInjectables() {
await browser.scripting.registerContentScripts(toAdd);
localRemove('$scripting.registerContentScripts');
} catch(reason) {
localWrite('$scripting.registerContentScripts', `${reason}`);
console.info(reason);
ubolErr(reason);
}
}

View file

@ -222,10 +222,8 @@ listen.onmessage = ev => {
}
if ( message.enabledRulesets !== undefined ) {
if ( hashFromIterable(message.enabledRulesets) !== hashFromIterable(local.enabledRulesets) ) {
local.enabledRulesets = message.enabledRulesets;
render = true;
}
local.enabledRulesets = message.enabledRulesets;
render = true;
}
if ( render === false ) { return; }
@ -250,7 +248,7 @@ sendMessage({
}
listen();
}).catch(reason => {
console.trace(reason);
console.error(reason);
});
/******************************************************************************/

View file

@ -19,14 +19,11 @@
Home: https://github.com/gorhill/uBlock
*/
import {
localRead,
runtime,
sendMessage,
} from './ext.js';
import { dnr } from './ext-compat.js';
import { dom } from './dom.js';
import { getConsoleOutput } from './debug.js';
import { getDefaultFilteringMode } from './mode-manager.js';
import { getEffectiveUserRules } from './ruleset-manager.js';
import { runtime } from './ext.js';
/******************************************************************************/
@ -63,15 +60,11 @@ export async function getTroubleshootingInfo(siteMode) {
rulesets,
defaultMode,
userRules,
registerContentScriptsReason,
unregisterContentScriptsReason,
] = await Promise.all([
runtime.getPlatformInfo(),
dnr.getEnabledRulesets(),
sendMessage({ what: 'getDefaultFilteringMode' }),
sendMessage({ what: 'getEffectiveUserRules' }),
localRead('$scripting.registerContentScripts'),
localRead('$scripting.unregisterContentScripts'),
getDefaultFilteringMode(),
getEffectiveUserRules(),
]);
const browser = (( ) => {
const extURL = runtime.getURL('');
@ -85,7 +78,6 @@ export async function getTroubleshootingInfo(siteMode) {
} else {
agent = 'Chrome';
}
dom.cl.add('html', agent.toLowerCase());
if ( /\bMobile\b/.test(navigator.userAgent) ) {
agent += ' Mobile';
}
@ -113,11 +105,11 @@ export async function getTroubleshootingInfo(siteMode) {
config['user rules'] = userRules.length;
}
config.rulesets = rulesets;
if ( registerContentScriptsReason !== undefined ) {
config.registerContentScripts = registerContentScriptsReason;
}
if ( unregisterContentScriptsReason !== undefined ) {
config.unregisterContentScripts = unregisterContentScriptsReason;
const consoleOutput = getConsoleOutput();
if ( consoleOutput.length !== 0 ) {
config.console = siteMode
? consoleOutput.slice(-8)
: consoleOutput;
}
return renderData(config);
}