From 8776c30e361981b86dbf6bcc194425a65c00be46 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Wed, 6 Sep 2023 18:53:06 +0600 Subject: [PATCH] error handling updated for cleanApkApps. --- .../e/apps/data/fused/FusedApiImpl.kt | 126 ++++++++---------- .../apps/data/gplay/utils/GPlayHttpClient.kt | 8 +- 2 files changed, 61 insertions(+), 73 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt index e86b5c68d..6a7cbec24 100644 --- a/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/fused/FusedApiImpl.kt @@ -99,7 +99,9 @@ class FusedApiImpl @Inject constructor( private const val CATEGORY_OPEN_GAMES_ID = "game_open_games" private const val CATEGORY_OPEN_GAMES_TITLE = "Open games" private const val ERROR_GPLAY_API = "Gplay api has faced error!" - private const val ERROR_GPLAY_SOURCE_NOT_SELECTED = "Gplay apps are not selected!" + private const val TIMEOUT = "Timeout" + private const val UNKNOWN = "Unknown" + private const val STATUS = "Status: " } /** @@ -166,12 +168,12 @@ class FusedApiImpl @Inject constructor( ): ResultSupreme> { val result = when (source) { - Source.GPLAY -> handleResultFromAppSources> { + Source.GPLAY -> handleNetworkResult> { priorList.addAll(fetchGPlayHome(authData)) priorList } - Source.OPEN -> handleResultFromAppSources { + Source.OPEN -> handleNetworkResult { val response = (cleanApkAppsRepository.getHomeScreenData() as Response).body() response?.home?.let { @@ -180,7 +182,7 @@ class FusedApiImpl @Inject constructor( priorList } - Source.PWA -> handleResultFromAppSources { + Source.PWA -> handleNetworkResult { val response = (cleanApkPWARepository.getHomeScreenData() as Response).body() response?.home?.let { @@ -290,7 +292,7 @@ class FusedApiImpl @Inject constructor( packageSpecificResults: ArrayList ): ResultSupreme, Boolean>> { val pwaApps: MutableList = mutableListOf() - val status = runCodeWithTimeout({ + val result = handleNetworkResult { val apps = cleanApkPWARepository.getSearchResult(query).body()?.apps apps?.apply { @@ -298,14 +300,14 @@ class FusedApiImpl @Inject constructor( pwaApps.addAll(this) } } - }) + } - if (pwaApps.isNotEmpty() || status != ResultStatus.OK) { + if (pwaApps.isNotEmpty() || result.getResultStatus() != ResultStatus.OK) { searchResult.addAll(pwaApps) } return ResultSupreme.create( - status, + result.getResultStatus(), Pair( filterWithKeywordSearch( searchResult, @@ -323,7 +325,7 @@ class FusedApiImpl @Inject constructor( searchResult: MutableList, packageSpecificResults: ArrayList ): ResultSupreme, Boolean>> { - val result = handleResultFromAppSources { + val result = handleNetworkResult { cleanApkResults.addAll(getCleanAPKSearchResults(query)) cleanApkResults } @@ -353,7 +355,7 @@ class FusedApiImpl @Inject constructor( var gplayPackageResult: FusedApp? = null var cleanapkPackageResult: FusedApp? = null - val status = runCodeWithTimeout({ + val result = handleNetworkResult { if (preferenceManagerModule.isGplaySelected()) { gplayPackageResult = getGplayPackagResult(query, authData) } @@ -361,7 +363,7 @@ class FusedApiImpl @Inject constructor( if (preferenceManagerModule.isOpenSourceSelected()) { cleanapkPackageResult = getCleanApkPackageResult(query) } - }) + } /* * Currently only show open source package result if exists in both fdroid and gplay. @@ -380,10 +382,10 @@ class FusedApiImpl @Inject constructor( * If there was a timeout, return it and don't try to fetch anything else. * Also send true in the pair to signal more results being loaded. */ - if (status != ResultStatus.OK) { - return ResultSupreme.create(status, Pair(packageSpecificResults, false)) + if (result.getResultStatus() != ResultStatus.OK) { + return ResultSupreme.create(result.getResultStatus(), Pair(packageSpecificResults, false)) } - return ResultSupreme.create(status, Pair(packageSpecificResults, true)) + return ResultSupreme.create(result.getResultStatus(), Pair(packageSpecificResults, true)) } /* @@ -448,7 +450,7 @@ class FusedApiImpl @Inject constructor( */ private suspend fun getCleanapkSearchResult(packageName: String): ResultSupreme { var fusedApp = FusedApp() - val status = runCodeWithTimeout({ + val result = handleNetworkResult { val result = cleanApkAppsRepository.getSearchResult( packageName, "package_name" @@ -457,15 +459,15 @@ class FusedApiImpl @Inject constructor( if (result?.apps?.isNotEmpty() == true && result.numberOfResults == 1) { fusedApp = result.apps[0] } - }) - return ResultSupreme.create(status, fusedApp) + } + return ResultSupreme.create(result.getResultStatus(), fusedApp) } override suspend fun getSearchSuggestions(query: String): List { var searchSuggesions = listOf() - runCodeWithTimeout({ + handleNetworkResult { searchSuggesions = gplayRepository.getSearchSuggestions(query) - }) + } return searchSuggesions } @@ -525,7 +527,7 @@ class FusedApiImpl @Inject constructor( override suspend fun getPWAApps(category: String): ResultSupreme, String>> { val list = mutableListOf() - val status = runCodeWithTimeout({ + val result = handleNetworkResult { val response = getPWAAppsResponse(category) response?.apps?.forEach { it.updateStatus() @@ -533,13 +535,13 @@ class FusedApiImpl @Inject constructor( it.updateFilterLevel(null) list.add(it) } - }) - return ResultSupreme.create(status, Pair(list, "")) + } + return ResultSupreme.create(result.getResultStatus(), Pair(list, "")) } override suspend fun getOpenSourceApps(category: String): ResultSupreme, String>> { val list = mutableListOf() - val status = runCodeWithTimeout({ + val result = handleNetworkResult { val response = getOpenSourceAppsResponse(category) response?.apps?.forEach { it.updateStatus() @@ -547,8 +549,8 @@ class FusedApiImpl @Inject constructor( it.updateFilterLevel(null) list.add(it) } - }) - return ResultSupreme.create(status, Pair(list, "")) + } + return ResultSupreme.create(result.getResultStatus(), Pair(list, "")) } /* @@ -559,7 +561,7 @@ class FusedApiImpl @Inject constructor( */ override suspend fun getCleanapkAppDetails(packageName: String): Pair { var fusedApp = FusedApp() - val status = runCodeWithTimeout({ + val result = handleNetworkResult { val result = cleanApkAppsRepository.getSearchResult( packageName, "package_name" @@ -571,8 +573,8 @@ class FusedApiImpl @Inject constructor( ?: FusedApp() } fusedApp.updateFilterLevel(null) - }) - return Pair(fusedApp, status) + } + return Pair(fusedApp, result.getResultStatus()) } override suspend fun getApplicationDetails( @@ -616,7 +618,7 @@ class FusedApiImpl @Inject constructor( * i.e. check timeout for individual package query. */ for (packageName in packageNameList) { - status = runCodeWithTimeout({ + val result = handleNetworkResult { cleanApkAppsRepository.getSearchResult( packageName, "package_name" @@ -629,7 +631,9 @@ class FusedApiImpl @Inject constructor( ) } } - }) + } + + status = result.getResultStatus() /* * If status is not ok, immediately return. @@ -655,7 +659,7 @@ class FusedApiImpl @Inject constructor( /* * Old code moved from getApplicationDetails() */ - val status = runCodeWithTimeout({ + val result = handleNetworkResult { gplayRepository.getAppsDetails(packageNameList).forEach { app -> /* * Some apps are restricted to locations. Example "com.skype.m2". @@ -672,9 +676,9 @@ class FusedApiImpl @Inject constructor( ) } } - }) + } - return Pair(fusedAppList, status) + return Pair(fusedAppList, result.getResultStatus()) } /** @@ -693,7 +697,7 @@ class FusedApiImpl @Inject constructor( appList: List, ): ResultSupreme> { val filteredFusedApps = mutableListOf() - return handleResultFromAppSources { + return handleNetworkResult { appList.forEach { val filter = getAppFilterLevel(it, authData) if (filter.isUnFiltered()) { @@ -784,7 +788,7 @@ class FusedApiImpl @Inject constructor( var response: FusedApp? = null - val result = handleResultFromAppSources { + val result = handleNetworkResult { response = if (origin == Origin.CLEANAPK) { (cleanApkAppsRepository.getAppDetails(id) as Response).body()?.app } else { @@ -851,7 +855,7 @@ class FusedApiImpl @Inject constructor( ): ResultSupreme> { val categoryList = mutableListOf() - return handleResultFromAppSources { + return handleNetworkResult { val playResponse = gplayRepository.getCategories(type).map { app -> val category = app.transformToFusedCategory() updateCategoryDrawable(category) @@ -865,10 +869,8 @@ class FusedApiImpl @Inject constructor( private suspend fun fetchPWACategories( type: CategoryType, ): Triple, String> { - var errorApplicationCategory = "" - var apiStatus: ResultStatus = ResultStatus.OK val fusedCategoriesList = mutableListOf() - runCodeWithTimeout({ + val result = handleNetworkResult { getPWAsCategories()?.let { fusedCategoriesList.addAll( getFusedCategoryBasedOnCategoryType( @@ -876,23 +878,16 @@ class FusedApiImpl @Inject constructor( ) ) } - }, { - errorApplicationCategory = APP_TYPE_PWA - apiStatus = ResultStatus.TIMEOUT - }, { - errorApplicationCategory = APP_TYPE_PWA - apiStatus = ResultStatus.UNKNOWN - }) - return Triple(apiStatus, fusedCategoriesList, errorApplicationCategory) + } + + return Triple(result.getResultStatus(), fusedCategoriesList, APP_TYPE_PWA) } private suspend fun fetchOpenSourceCategories( type: CategoryType, ): Triple, String> { - var errorApplicationCategory = "" - var apiStatus: ResultStatus = ResultStatus.OK val fusedCategoryList = mutableListOf() - runCodeWithTimeout({ + val result = handleNetworkResult { getOpenSourceCategories()?.let { fusedCategoryList.addAll( getFusedCategoryBasedOnCategoryType( @@ -902,14 +897,9 @@ class FusedApiImpl @Inject constructor( ) ) } - }, { - errorApplicationCategory = APP_TYPE_OPEN - apiStatus = ResultStatus.TIMEOUT - }, { - errorApplicationCategory = APP_TYPE_OPEN - apiStatus = ResultStatus.UNKNOWN - }) - return Triple(apiStatus, fusedCategoryList, errorApplicationCategory) + } + + return Triple(result.getResultStatus(), fusedCategoryList, APP_TYPE_OPEN) } /** @@ -1077,12 +1067,12 @@ class FusedApiImpl @Inject constructor( query: String, nextPageSubBundle: Set? ): GplaySearchResult { - return handleResultFromAppSources { + return handleNetworkResult { val searchResults = gplayRepository.getSearchResult(query, nextPageSubBundle?.toMutableSet()) if (!preferenceManagerModule.isGplaySelected()) { - return@handleResultFromAppSources Pair(listOf(), setOf()) + return@handleNetworkResult Pair(listOf(), setOf()) } val fusedAppList = @@ -1092,19 +1082,17 @@ class FusedApiImpl @Inject constructor( fusedAppList.add(FusedApp(isPlaceHolder = true)) } - return@handleResultFromAppSources Pair(fusedAppList.toList(), searchResults.second.toSet()) + return@handleNetworkResult Pair(fusedAppList.toList(), searchResults.second.toSet()) } } - private suspend fun handleResultFromAppSources(call: suspend () -> T): ResultSupreme { + private suspend fun handleNetworkResult(call: suspend () -> T): ResultSupreme { return try { ResultSupreme.Success(call()) } catch (e: SocketTimeoutException) { val message = extractErrorMessage(e) - val exception = GPlayException(true, message) - val resultTimeout = ResultSupreme.Timeout(exception = exception) + val resultTimeout = ResultSupreme.Timeout(exception = e) resultTimeout.message = message - resultTimeout } catch (e: GplayHttpRequestException) { val message = extractErrorMessage(e) @@ -1120,12 +1108,12 @@ class FusedApiImpl @Inject constructor( private fun extractErrorMessage(e: Exception): String { val status = when (e) { is GplayHttpRequestException -> e.status.toString() - is SocketTimeoutException -> "Timeout" - else -> "Unknown" + is SocketTimeoutException -> TIMEOUT + else -> UNKNOWN } return (e.localizedMessage?.ifBlank { ERROR_GPLAY_API } - ?: ERROR_GPLAY_API) + "Status: $status" + ?: ERROR_GPLAY_API) + "$STATUS$status" } /* @@ -1430,7 +1418,7 @@ class FusedApiImpl @Inject constructor( var fusedAppList: MutableList = mutableListOf() var nextPageUrl = "" - return handleResultFromAppSources { + return handleNetworkResult { val streamCluster = gplayRepository.getAppsByCategory(category, pageUrl) as StreamCluster diff --git a/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt b/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt index 692e76f0d..a123e685e 100644 --- a/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt +++ b/app/src/main/java/foundation/e/apps/data/gplay/utils/GPlayHttpClient.kt @@ -39,6 +39,7 @@ import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import timber.log.Timber import java.io.IOException +import java.net.Socket import java.net.SocketTimeoutException import java.net.UnknownHostException import java.util.concurrent.TimeUnit @@ -54,13 +55,11 @@ class GPlayHttpClient @Inject constructor( companion object { private const val TAG = "GPlayHttpClient" private const val HTTP_TIMEOUT_IN_SECOND = 10L - <<<<<<< HEAD private const val SEARCH = "search" private const val SEARCH_SUGGEST = "searchSuggest" private const val STATUS_CODE_UNAUTHORIZED = 401 private const val STATUS_CODE_TOO_MANY_REQUESTS = 429 - ======= - >>>>>>> ea7f47e2 (error handling updated for search and homepage) + } private val okHttpClient = OkHttpClient().newBuilder() @@ -167,7 +166,8 @@ class GPlayHttpClient @Inject constructor( response = call.execute() buildPlayResponse(response) } catch (e: Exception) { - throw e + val status = if (e is SocketTimeoutException) 408 else -1 + throw GplayHttpRequestException(status, e.localizedMessage ?: "") } finally { response?.close() } -- GitLab