Skip to content

fetchJson does not handle cases, where JSON fetching errors? #993

@rugk

Description

@rugk

Background

I was searching for how the i18n/locale is fetched and where/how the fallback to en is implemented or how it (apparently?) auto-detects the language. As in my case, it is in German.

I've found the file, which fetching it like this:

async function fetchJSON(src) {
if (fetchCache[src]) {
return fetchCache[src]
}
const response = await fetch(src)
const json = await response.json()
fetchCache[src] = json
return json
}

Problems

IMHO, problems here:

  • E.g. I could pass en-US in locale and the fetching there would fail. I don't see any fallback to English directly there.
  • Also in case the fetching fails for some reason, there is no logging or any other handling I see? Would not a simple console.error be good?

Proposal

In my case, I've implemented this like this:

        i18n: async () => {
            let locale = browser.i18n.getUILanguage();
            console.log("Getting i18n for", locale);
            let response = await fetch(browser.runtime.getURL(`/node_modules/@emoji-mart/data/i18n/${locale}.json`));

            if (!response.ok) {
                console.warn("Getting", locale, "failed. Trying base locale.", response);
                locale = getBaseLanguageTag();
                console.log("Getting i18n for", locale, "…");
                response = await fetch(browser.runtime.getURL(`/node_modules/@emoji-mart/data/i18n/${locale}.json`));
            }
            if (!response.ok) {
                console.warn("Getting", locale, "fallback failed. Trying base locale.", response);
                locale = "en";
                console.log("Getting i18n for", locale, "…");
                response = await fetch(browser.runtime.getURL(`/node_modules/@emoji-mart/data/i18n/${locale}.json`));
            }
            if (!response.ok) {
                console.error("Getting English fallback failed.", response);
            }

            const i18nResponse = await response.json();
            i18nResponse.pick = browser.i18n.getMessage("extensionNameShort") // show the extension name by default
            return i18nResponse;
        },

Note as this is a WebExtension/browser extension, I am getting the current language via the special getUILanguage API, which for other use cases makes no sense/is not available.
Also the language overwrite is also a custom addition.

Edit: Note that I also had to adjust the handling to also catch errors, as in this very special case of a WebExtension. See mdn/content#39197 for details.

Additional details

I've shown this example for the locale, but the same fetchJSON function is obviously used for other stuff like the emoji set.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions