From 2ccbb9bc008f2f13bffe0f731dd921e3b4d81aca Mon Sep 17 00:00:00 2001 From: Aman Agrawal Date: Wed, 17 Apr 2024 06:30:05 +0000 Subject: [PATCH] emojisets: Improve error handling when we fail to fetch an emojiset. Now we retry 3 times with 10s delays before giving up if on loading the emoji. Hopefully user will just refresh the page by that time if the emojis still can't be displayed. --- web/src/emojisets.ts | 60 ++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/web/src/emojisets.ts b/web/src/emojisets.ts index 46847b2bb8987..6abe738c68f6b 100644 --- a/web/src/emojisets.ts +++ b/web/src/emojisets.ts @@ -29,25 +29,53 @@ emojisets.set("text", emojisets.get("google")!); let current_emojiset: EmojiSet | undefined; async function fetch_emojiset(name: string, url: string): Promise { - return new Promise((resolve, _reject) => { - const get_emojiset = (): void => { - const sheet = new Image(); - sheet.addEventListener("load", () => { - window.removeEventListener("online", get_emojiset); - resolve(); - }); - sheet.addEventListener("error", () => { - // If there's an error, try again when the browser is online - window.addEventListener("online", get_emojiset); + const MAX_RETRIES = 3; + const RETRY_DELAY = 10000; // 10 seconds + + for (let attempt = 1; attempt <= MAX_RETRIES; attempt += 1) { + try { + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + // If the fetch is successful, resolve the promise and return + return; + } catch (error) { + if (!navigator.onLine) { + // If the user is offline, retry once they are online. + await new Promise((resolve) => { + // We don't want to throw an error here since this is clearly something wrong with user's network. + blueslip.warn( + `Failed to load emojiset ${name} from ${url}. Retrying when online.`, + ); + window.addEventListener( + "online", + () => { + resolve(); + }, + {once: true}, + ); + }); + } else { blueslip.warn( - `Failed to load emojiset ${name} from ${url}. A retry will be attempted when the browser is online.`, + `Failed to load emojiset ${name} from ${url}. Attempt ${attempt} of ${MAX_RETRIES}.`, ); - }); - sheet.src = url; - }; - get_emojiset(); - }); + // If this was the last attempt, rethrow the error + if (attempt === MAX_RETRIES) { + blueslip.error( + `Failed to load emojiset ${name} from ${url} after ${MAX_RETRIES} attempts.`, + ); + throw error; + } + + // Wait before the next attempt + await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY)); + } + } + } } export async function select(name: string): Promise {