Need help with bug in Context Search

On the Options page, clicking on a setting generates the following error in the debug console:

Strangely, the line number isn’t specified!

This code handles the checkbox click in options.js:

function updateTabMode() {
    if (sameTab.checked || openSidebar.checked) {
        active.style.visibility = "hidden";
    } else {
        active.style.visibility = "visible";
    }
    let data = {};
	data["tabMode"] = document.querySelector('input[name="results"]:checked').value;
	data["tabActive"] = tabActive.checked;
	sendMessage("updateTabMode", data);
}

and the following code should handle the message received in background.js from options.js:

browser.runtime.onMessage.addListener(handleMessages);
async function handleMessages(message, sender, sendResponse) {
    let id = "";
    let domain = "";
    switch (message.action) {
        case "updateTabMode": {
            const settings = await getOptions();
            let options = settings.options;
            if (logToConsole) console.log(`Preferences retrieved from storage sync: ${JSON.stringify(options)}`);
            options.tabMode = message.data.tabMode;
            options.tabActive = message.data.tabActive;
            setTabMode(options);
            await saveOptions(options, false);
            break;
        }

When I define getOptions as follows, the code works:

async function getOptions(){
    return new Promise(
        (resolve, reject) => {
            browser.storage.sync.get(null).then(resolve, reject);
        }
    );
}

It failed previously with getOptions defined as follows:

async function getOptions(){
    try {
        let data = await browser.storage.sync.get("options");
        if (logToConsole) console.log(JSON.stringify(data));
        return data;
    } catch (err) {
        if (logToConsole) {
            console.error(err);
            console.log("Failed to retrieve options from storage sync.");
        }
    }
}

What is the reason for the second async version failing?

I really hate to say this, but if you have troubles with debugging some bugs, use Chrome :slight_smile: . Often you’ll see totally different error there pointing to the right direction.

If you can’t use Chrome, then use the debugger to go through your code. You can easily debug everything, including background script. There is also debugger; statement you can use to invoke debugger in complicated conditions.

Firefox extensions need to be adapted to work in Chrome if I’m not mistaken, e.g. replacing browser.menus.create with chrome.menus.create, etc.

Things would quickly get very messy juggling between ffx and chrome extension versions.

This could just be const getOptions = () => browser.storage.sync.get(null);

The really weird thing to me is that your error has no line number, but I guess that’s due to it rejecting in the onMessage listener. Why I’m suspicious of that is mainly due to the order of your logs.

P.S.: No need to stringify objects to log them, just do console.log(data).

OK, I don’t know what the difference is btwn using a function assigned to a var and declaring it as a var.

That’s not the difference I was trying to show (the difference is pretty small btw), I was trying to show that there’s no need to have the function be async if it just returns a single promise and to wrap something that returns a promise into a new Promise call.

Also, that response was submitted prelimiarily, so I updated it further, please look at it again.

I tried replacing the async function with the above and it failed. The context menu would no longer be displayed.

To me, looks like everything is trial and error in JS.

Regarding Chrome support - all you need to do is use webextension-polyfill library. It’s easier than it sounds. After that, most of the code should work on Chrome without any issues as the API is the same.

Actually, MDN recommends this workaround even

That is honestly very bad advice. If you’re in a situation where the logged object is mutated and you want to see it pre-mutation, you should be using the debugger (debugger; instead of console.log();). Further using JSON.stringify will lead to you losing a bunch of information compared to the live view. It won’t he able to handle cyclic references, you won’t get any info on the constructor and prototype chain, as well as no information on getters/setters or methods on the method. This also applies to other JSON incompatible types like regexp, maps and similar or symbolic keys. Lastly you will not get to see all properties on the object if they’re hidden in a specific way (non-enumerable?).

Well… don’t discuss that with me, but with the authors of that MDN page. Open an issue (or Discourse thread?) or adjust it directly… :wink: