Author: Adam <git@apiote.xyz>
better handle errors, esp. with regard to rate limiting
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt b/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt index 7f89c0ec8c12615e02ded718ef99a59e139cdfc8..3b34947f08ab9c64c6358eedea3554e11ed538b8 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/api/Api.kt @@ -9,6 +9,7 @@ import ml.adamsprogs.bimba.R import java.io.IOException import java.io.InputStream import java.net.HttpURLConnection +import java.net.MalformedURLException import java.net.URL import java.net.URLEncoder @@ -32,11 +33,15 @@ data class Error(val statusCode: Int, val stringResource: Int, val imageResource: Int) suspend fun getFeeds(cm: ConnectivityManager, server: Server): Result { - return rawRequest( - URL("${hostWithScheme(server.host)}/api/"), - server, - cm - ) // todo(error-handling) if is not a valid URL + return try { + rawRequest( + URL("${hostWithScheme(server.host)}/api/"), + server, + cm + ) + } catch(_: MalformedURLException) { + Result(null, Error(0, R.string.error_url, R.drawable.error_url)) + } } suspend fun queryItems( diff --git a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt index 0e9c6f6774f07dabce5868eb16e16345c3df6ac7..e5674398314ca6c30930d625d5940fc9e48ca464 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/home/HomeViewModel.kt @@ -24,16 +24,11 @@ fun getItems(cm: ConnectivityManager, server: Server, query: String) { viewModelScope.launch { val itemsResult = queryItems(cm, server, query, limit = 6) - if (itemsResult.stream == null) { // todo first check error + if (itemsResult.error != null) { Log.e("HVM.getItems", "$itemsResult") } else { - val response = unmarshallItemResponse(itemsResult.stream) - if (itemsResult.error == null) { - mutableItems.value = (response as ItemsSuccess).items - } else { - Log.w("HVM.getItems", "$itemsResult") - Log.w("HVM.getItems", "$response") - } + val response = unmarshallItemResponse(itemsResult.stream!!) + mutableItems.value = (response as ItemsSuccess).items } } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/map/MapViewModel.kt b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/map/MapViewModel.kt index 63e618f42daa552f00809b26e99af333dc5d886c..b9bd6d54ba976f4237bee03c105784a463c44199 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/map/MapViewModel.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/dashboard/ui/map/MapViewModel.kt @@ -34,16 +34,11 @@ fun getLocatablesIn(cm: ConnectivityManager, server: Server, bl: Position, tr: Position) { viewModelScope.launch { val locatablesResult = ml.adamsprogs.bimba.api.getLocatablesIn(cm, server, bl, tr) - val response = if (locatablesResult.stream != null) { // todo first check error - unmarshallLocatablesResponse(locatablesResult.stream) - } else { - null - } if (locatablesResult.error != null) { Log.e("Results.location", "$locatablesResult") - Log.e("Results.location", "$response") //todo showError(itemsResult.error) } else { + val response = unmarshallLocatablesResponse(locatablesResult.stream!!) _items.value = (response as LocatablesSuccess).locatables } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt index f28c8c14cf358f172cd04f03fe8434c9c8fcc8b8..e15ba288a6f5e5efc51f1602770bd5c6cf7d4084 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/search/ResultsActivity.kt @@ -16,7 +16,6 @@ import androidx.appcompat.content.res.AppCompatResources import androidx.core.view.WindowCompat import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.coroutines.* -import kotlinx.coroutines.Runnable import ml.adamsprogs.bimba.R import ml.adamsprogs.bimba.api.* import ml.adamsprogs.bimba.databinding.ActivityResultsBinding @@ -124,16 +123,11 @@ private fun getItemsByQuery(server: Server, query: String) { val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager MainScope().launch { val itemsResult = queryItems(cm, server, query) - val response = if (itemsResult.stream != null) { // todo first check error - unmarshallItemResponse(itemsResult.stream) - } else { - null - } if (itemsResult.error != null) { Log.e("Results.query", "$itemsResult") - Log.e("Results.query", "$response") showError(itemsResult.error) } else { + val response = unmarshallItemResponse(itemsResult.stream!!) updateItems((response as ItemsSuccess).items) } } @@ -143,16 +137,11 @@ private fun getItemsByLocation(server: Server, position: Position) { val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager MainScope().launch { val itemsResult = locateItems(cm, server, position) - val response = if (itemsResult.stream != null) { // todo first check error - unmarshallItemResponse(itemsResult.stream) - } else { - null - } if (itemsResult.error != null) { Log.e("Results.location", "$itemsResult") - Log.e("Results.location", "$response") showError(itemsResult.error) } else { + val response = unmarshallItemResponse(itemsResult.stream!!) updateItems((response as ItemsSuccess).items) } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/settings/ServerChooserActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/settings/ServerChooserActivity.kt index 99e6540ac6471b06e25eb5d5c1a85cc7b27a4ecc..5834d738306c49f102253ad222c965047e5cc14d 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/settings/ServerChooserActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/settings/ServerChooserActivity.kt @@ -12,10 +12,8 @@ import androidx.appcompat.content.res.AppCompatResources import androidx.core.content.edit import androidx.core.widget.addTextChangedListener import com.google.android.material.dialog.MaterialAlertDialogBuilder -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import ml.adamsprogs.bimba.R import ml.adamsprogs.bimba.api.FeedsResponse import ml.adamsprogs.bimba.api.FeedsSuccess @@ -108,30 +106,23 @@ showDialog(R.string.error, result.error.stringResource, result.error.imageResource, null) return@launch } - val response = withContext(Dispatchers.IO) { - FeedsResponse.unmarshal(result.stream!!) + val response = FeedsResponse.unmarshal(result.stream!!) as FeedsSuccess + val token = preferences.getString("token", "") + if (response.private && token == "") { + showDialog(R.string.error, R.string.server_private_question, R.drawable.error_sec, null) + return@launch } - if (response is FeedsSuccess) { - val token = preferences.getString("token", "") - if (response.rateLimited && token == "") { - showDialog( - R.string.rate_limit, - R.string.server_rate_limited_question, - R.drawable.error_limit - ) { - runFeedsActivity() - } - return@launch + if (response.rateLimited && token == "") { + showDialog( + R.string.rate_limit, + R.string.server_rate_limited_question, + R.drawable.error_limit + ) { + runFeedsActivity() } - if (response.private && token == "") { - showDialog(R.string.error, R.string.server_private_question, R.drawable.error_sec, null) - return@launch - } - runFeedsActivity() - } else { - // todo error handling - // todo [api-freeze] check api version + return@launch } + runFeedsActivity() } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/settings/feeds/FeedChooserActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/settings/feeds/FeedChooserActivity.kt index d3527ffcc914b5ed7fb8e9cdd1989b7218849aad..f88d41691203b2ac081947a674be713c0fc27960 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/settings/feeds/FeedChooserActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/settings/feeds/FeedChooserActivity.kt @@ -9,10 +9,8 @@ import android.util.Log import android.view.View import androidx.core.content.edit import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import ml.adamsprogs.bimba.api.FeedsResponse import ml.adamsprogs.bimba.api.FeedsSuccess import ml.adamsprogs.bimba.api.Server @@ -58,14 +56,8 @@ if (feedsResult.error != null) { Log.w("FeedChooser", "$feedsResult") return@launch } - val response = withContext(Dispatchers.IO) { - FeedsResponse.unmarshal(feedsResult.stream!!) - } - if (response is FeedsSuccess) { - updateItems(response) - } else { - // todo error handling - } + val response = FeedsResponse.unmarshal(feedsResult.stream!!) + updateItems(response as FeedsSuccess) } } diff --git a/app/src/main/res/drawable/error_url.xml b/app/src/main/res/drawable/error_url.xml new file mode 100644 index 0000000000000000000000000000000000000000..a8ffe8655e79b9f68645b52061550fd59a8742d9 --- /dev/null +++ b/app/src/main/res/drawable/error_url.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1 0,1.43 -0.98,2.63 -2.31,2.98l1.46,1.46C20.88,15.61 22,13.95 22,12c0,-2.76 -2.24,-5 -5,-5zM16,11h-2.19l2,2L16,13zM2,4.27l3.11,3.11C3.29,8.12 2,9.91 2,12c0,2.76 2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1 0,-1.59 1.21,-2.9 2.76,-3.07L8.73,11L8,11v2h2.73L13,15.27L13,17h1.73l4.01,4L20,19.74 3.27,3 2,4.27z"/> +</vector> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c96a09b54dbf4154386909b6aafcb82956f88aad..d45d164004ed6874ade857eac4f9e76cabfed86c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,4 +82,5 @@Last update: %s <string name="title_feeds">Feeds</string> <string name="title_servers">Servers</string> <string name="title_cities">Cities</string> + <string name="error_url">Malformed URL provided</string> </resources> \ No newline at end of file