Bimba.git

commit 9dfaa8ee96518eccd73c12a04358107b40e5aecd

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