User: kyle wood Date: 20 Jun 23 03:28 Revision: 3550f84825a4fb94ba63eb709bb69bb8795987cc Summary: Fix version json HTTP errors The main issue is we were catching IOException after switching to fuel, which wraps all exceptions in FuelError, so we weren't actually going to the GitHub fallback. We also saw this issue prior to switching to fuel, so as a failsafe to the failsafe, I've added another fallback URL, hosted in a different location, as a last-ditch effort to connect to something. TeamCity URL: https://ci.mcdev.io/viewModification.html?tab=vcsModificationFiles&modId=8542&personal=false Index: src/main/kotlin/creator/PlatformVersion.kt =================================================================== --- src/main/kotlin/creator/PlatformVersion.kt (revision 10534e39fa8f2a876057f437d6ee0a13f9546de9) +++ src/main/kotlin/creator/PlatformVersion.kt (revision 3550f84825a4fb94ba63eb709bb69bb8795987cc) @@ -23,6 +23,9 @@ import com.demonwav.mcdev.platform.PlatformType import com.demonwav.mcdev.update.PluginUtil import com.demonwav.mcdev.util.fromJson +import com.demonwav.mcdev.util.mapFirstNotNull +import com.demonwav.mcdev.util.withSuppressed +import com.github.kittinunf.fuel.core.FuelError import com.github.kittinunf.fuel.core.FuelManager import com.github.kittinunf.fuel.core.requests.suspendable import com.github.kittinunf.fuel.coroutines.awaitString @@ -35,9 +38,21 @@ import java.net.URI import kotlin.reflect.KClass -private const val CLOUDFLARE_BASE_URL = "https://minecraftdev.org/versions/" +// Cloudflare and GitHub are both global CDNs +// Cloudflare is used first / preferred simply due to domain preference +private const val CLOUDFLARE_BASE_URL = "https://mcdev.io/versions/" +// Directly retrieving the file via GitHub is the second option. In some regions / networks Cloudflare is blocked, +// but we may still be able to reach GitHub private const val GITHUB_BASE_URL = "https://raw.githubusercontent.com/minecraft-dev/minecraftdev.org/master/versions/" +// Finally, there are apparently also regions / networks where both Cloudflare and GitHub is blocked. +// Or maybe the domain `mcdev.io` (and prior to that, `minecraftdev.org`) is blocked due to weird domain +// rules (perhaps blocking on the word "minecraft"). In one last ditch effort to retrieve the version json +// we can also pull from this host, a separate host using a separate domain. This is an OVH server, not +// proxied through Cloudflare. +private const val OVH_BASE_URL = "https://versions.denwav.com/versions/" +private val URLS = listOf(CLOUDFLARE_BASE_URL, GITHUB_BASE_URL, OVH_BASE_URL) + val PLATFORM_VERSION_LOGGER = logger() suspend fun getVersionSelector(type: PlatformType): PlatformVersion { @@ -62,20 +77,17 @@ } suspend fun getText(path: String): String { - return try { - // attempt cloudflare - doCall(CLOUDFLARE_BASE_URL + path) - } catch (e: IOException) { - PLATFORM_VERSION_LOGGER.warn("Failed to reach cloudflare URL ${CLOUDFLARE_BASE_URL + path}", e) - // if that fails, attempt github + var thrown: FuelError? = null + return URLS.mapFirstNotNull { url -> try { - doCall(GITHUB_BASE_URL + path) - } catch (e: IOException) { - PLATFORM_VERSION_LOGGER.warn("Failed to reach fallback GitHub URL ${GITHUB_BASE_URL + path}", e) - throw e + doCall(url + path) + } catch (e: FuelError) { + PLATFORM_VERSION_LOGGER.warn("Failed to reach URL $url$path") + thrown = withSuppressed(thrown, e) + null } + } ?: throw thrown!! - } +} -} private suspend fun doCall(urlText: String): String { val manager = FuelManager() Index: src/main/kotlin/util/utils.kt =================================================================== --- src/main/kotlin/util/utils.kt (revision 10534e39fa8f2a876057f437d6ee0a13f9546de9) +++ src/main/kotlin/util/utils.kt (revision 3550f84825a4fb94ba63eb709bb69bb8795987cc) @@ -370,3 +370,6 @@ throw e } } + +fun withSuppressed(original: T?, other: T): T = + original?.apply { addSuppressed(other) } ?: other