fix bugs
This commit is contained in:
+21
-11
@@ -2,6 +2,7 @@ import type { AppConfig } from '@/config/types'
|
||||
import { readCachedAppConfig, writeCachedAppConfig } from '@/config/config-cache'
|
||||
|
||||
const CONFIG_SUCCESS_URL_KEY = 'CONFIG_Success_URL'
|
||||
export const CONFIG_RETRY_ROUNDS = 5
|
||||
|
||||
function getProtocol() {
|
||||
return window.location.protocol === 'https:' ? 'https:' : 'http:'
|
||||
@@ -29,6 +30,12 @@ export function sortConfigUrls(urls: string[]) {
|
||||
})
|
||||
}
|
||||
|
||||
function clearStaleConfigSuccessUrl(url: string) {
|
||||
if (localStorage.getItem(CONFIG_SUCCESS_URL_KEY) === url) {
|
||||
localStorage.removeItem(CONFIG_SUCCESS_URL_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchConfig(url: string, timeout = 3000): Promise<AppConfig> {
|
||||
const controller = new AbortController()
|
||||
const timeoutId = window.setTimeout(() => controller.abort(), timeout)
|
||||
@@ -59,22 +66,25 @@ async function fetchConfig(url: string, timeout = 3000): Promise<AppConfig> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchFreshAppConfig(): Promise<AppConfig> {
|
||||
export async function fetchFreshAppConfig(rounds = CONFIG_RETRY_ROUNDS): Promise<AppConfig> {
|
||||
const urls = sortConfigUrls(getConfigUrls())
|
||||
|
||||
for (let index = 0; index < urls.length; index++) {
|
||||
const url = urls[index]
|
||||
for (let round = 1; round <= rounds; round++) {
|
||||
for (let index = 0; index < urls.length; index++) {
|
||||
const url = urls[index]
|
||||
|
||||
try {
|
||||
const timeout = index === urls.length - 1 ? 5000 : 2500
|
||||
const config = await fetchConfig(url, timeout)
|
||||
try {
|
||||
const timeout = index === urls.length - 1 ? 7000 : 4000
|
||||
const config = await fetchConfig(url, timeout)
|
||||
|
||||
localStorage.setItem(CONFIG_SUCCESS_URL_KEY, url)
|
||||
writeCachedAppConfig(config)
|
||||
localStorage.setItem(CONFIG_SUCCESS_URL_KEY, url)
|
||||
writeCachedAppConfig(config)
|
||||
|
||||
return config
|
||||
} catch (error) {
|
||||
console.warn(`Config failed from ${url}`, error)
|
||||
return config
|
||||
} catch (error) {
|
||||
clearStaleConfigSuccessUrl(url)
|
||||
console.warn(`Config failed from ${url}. Round: ${round}`, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,16 +9,24 @@ type VersionResponse =
|
||||
}
|
||||
|
||||
const VERSION_SUCCESS_URL_KEY = 'VERSION_Success_URL'
|
||||
const VERSION_RETRY_ROUNDS = 5
|
||||
export const VERSION_RETRY_ROUNDS = 5
|
||||
|
||||
let versionFetchPromise: Promise<string | null> | null = null
|
||||
let cachedVersionResult: string | null | undefined
|
||||
|
||||
function getProtocol() {
|
||||
return window.location.protocol === 'https:' ? 'https:' : 'http:'
|
||||
}
|
||||
|
||||
function getVersionUrls() {
|
||||
const protocol = getProtocol()
|
||||
|
||||
return [
|
||||
'https://nerkh.gold/get_version',
|
||||
'https://tablo.talasevin.ir/get_version',
|
||||
'https://abshode-service.montgit.ir/server/get_version'
|
||||
'https://abshode-service.montgit.ir/server/get_version',
|
||||
`${protocol}//212.23.201.173:8381/get_version`,
|
||||
`${protocol}//91.212.174.137:4040/server/get_version`
|
||||
]
|
||||
}
|
||||
|
||||
@@ -33,6 +41,12 @@ function sortVersionUrls(urls: string[]) {
|
||||
return [lastSuccessUrl, ...others]
|
||||
}
|
||||
|
||||
function clearStaleVersionSuccessUrl(url: string) {
|
||||
if (localStorage.getItem(VERSION_SUCCESS_URL_KEY) === url) {
|
||||
localStorage.removeItem(VERSION_SUCCESS_URL_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
function readUserVersion(user: unknown) {
|
||||
if (!user || typeof user !== 'object' || Array.isArray(user)) {
|
||||
return ''
|
||||
@@ -82,7 +96,6 @@ async function fetchVersion(url: string, timeout = 3500): Promise<string | null>
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
// Non-2xx/timeout should be treated as "request failed" and we may try the next URL.
|
||||
throw new Error(`Version request failed with status ${response.status}`)
|
||||
}
|
||||
|
||||
@@ -94,10 +107,8 @@ async function fetchVersion(url: string, timeout = 3500): Promise<string | null>
|
||||
|
||||
const version = normalizeVersionResponse(data)
|
||||
|
||||
// IMPORTANT: if the request returned 200/ok, we stop here even if we couldn't extract a version.
|
||||
// This prevents unnecessary looping when the endpoint is "reachable" but returns an empty payload.
|
||||
if (!version) {
|
||||
return null
|
||||
throw new Error('Version response is empty')
|
||||
}
|
||||
|
||||
localStorage.setItem(VERSION_SUCCESS_URL_KEY, url)
|
||||
@@ -118,10 +129,11 @@ async function fetchVersionWithRetry(rounds = VERSION_RETRY_ROUNDS): Promise<str
|
||||
|
||||
try {
|
||||
const version = await fetchVersion(url, timeout)
|
||||
// fetchVersion only throws on real request failures (non-ok / timeout).
|
||||
// If it returns null, we got HTTP 200 but empty version => stop immediately.
|
||||
return version
|
||||
if (version) {
|
||||
return version
|
||||
}
|
||||
} catch (error) {
|
||||
clearStaleVersionSuccessUrl(url)
|
||||
console.warn(`Version failed from ${url}. Round: ${round}`, error)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user