Author: Adam Pioterek <adam.pioterek@protonmail.ch>
server error handling
app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt | 5 app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt | 14 app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt | 5 app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt | 5 app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt | 28 + app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt | 15 app/src/main/java/ml/adamsprogs/bimba/extensions.kt | 12 app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt | 4 app/src/main/res/values-de/strings.xml | 4 app/src/main/res/values-it/strings.xml | 4 app/src/main/res/values-nl/strings.xml | 4 app/src/main/res/values-pl/strings.xml | 4 app/src/main/res/values/strings.xml | 4 build.gradle | 2
diff --git a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt index c40abec7cc2d1edd1e714a8a4f24dbe6afb6d577..faedcc757de71be595d9cd42158d306e3d44964d 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt @@ -32,8 +32,9 @@ if (intent?.action == VmService.ACTION_READY) { val departures = intent.getStringArrayListExtra(VmService.EXTRA_DEPARTURES)?.map { Departure.fromString(it) }?.toSet() val plateId = intent.getSerializableExtra(VmService.EXTRA_PLATE_ID) as Plate.ID? val stopCode = intent.getSerializableExtra(VmService.EXTRA_STOP_CODE) as String + val code = intent.getIntExtra(VmService.EXTRA_CODE, 0) for (listener in onVmListeners) { - listener.onVm(departures, plateId, stopCode) + listener.onVm(departures, plateId, stopCode, code) } } } @@ -59,6 +60,6 @@ fun onTimetableDownload(result: String?) } interface OnVmListener { - fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID?, stopCode: String) + fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID?, stopCode: String, code: Int) } } \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt b/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt index 32dddcd358b1801b29be9440b9a0c0322cdb8460..45a60fc90e45adb61e3dd09c5a5ed12bbe9b7059 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt @@ -205,7 +205,7 @@ return timetable.getServiceFirstDay(service) } interface OnDeparturesReadyListener { - fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?) + fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) } inner class Request(private val listener: OnDeparturesReadyListener, private val segments: Set<StopSegment>) : MessageReceiver.OnVmListener { @@ -221,20 +221,24 @@ cache = constructSegmentDepartures(segments) } } - override fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID?, stopCode: String) { + override fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID?, stopCode: String, code: Int) { launch(UI) { + if ((plateId == null || vmDepartures == null) and (timetable.isEmpty())) { + listener.onDeparturesReady(emptyList(), null, code) + return@launch + } if (plateId == null) { - listener.onDeparturesReady(filterDepartures(cache!!.await()), null) + listener.onDeparturesReady(filterDepartures(cache!!.await()), null, code) } else { if (segments.any { plateId in it }) { if (vmDepartures != null) { - listener.onDeparturesReady(vmDepartures.toList(), plateId) + listener.onDeparturesReady(vmDepartures.toList(), plateId, code) if (plateId !in receivedPlates) receivedPlates.add(plateId) } else { receivedPlates.remove(plateId) if (receivedPlates.isEmpty()) { - listener.onDeparturesReady(filterDepartures(cache!!.await()), null) + listener.onDeparturesReady(filterDepartures(cache!!.await()), null, code) } } } diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt index 9320e22aef6596e5757970c7ba44d98b0c0afcf8..43f017d67c36885dd9a1accfb6cf4d083773eb7c 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt @@ -251,8 +251,9 @@ favouritesList.itemAnimator = DefaultItemAnimator() favouritesList.layoutManager = layoutManager } - override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?) { + override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) { favouritesList.adapter.notifyDataSetChanged() + showError(drawer_layout, code, this) } private fun getSuggestions() { @@ -298,7 +299,7 @@ } override fun onTimetableDownload(result: String?) { val message: String = when (result) { - TimetableDownloader.RESULT_NO_CONNECTIVITY -> getString(R.string.no_connectivity) + TimetableDownloader.RESULT_NO_CONNECTIVITY -> getString(R.string.no_connectivity_cant_update) TimetableDownloader.RESULT_UP_TO_DATE -> getString(R.string.timetable_up_to_date) TimetableDownloader.RESULT_FINISHED -> getString(R.string.timetable_downloaded) else -> getString(R.string.error_try_later) diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt index b6dbb3eeab4dbf3ca1b8ef2bd3077c7276377fd9..8aeed16739529be5f2f5f927660fa12f76fd659f 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt @@ -137,7 +137,8 @@ } else favourite!!.subscribeForDepartures(this, context) } - override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?) { + override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) { + showError(stop_layout, code, this) if (plateId == null) { this.departures.clear() this.departures[Plate.ID.dummy] = departures @@ -164,7 +165,7 @@ } override fun onTimetableDownload(result: String?) { val message: String = when (result) { - TimetableDownloader.RESULT_NO_CONNECTIVITY -> getString(R.string.no_connectivity) + TimetableDownloader.RESULT_NO_CONNECTIVITY -> getString(R.string.no_connectivity_cant_update) TimetableDownloader.RESULT_UP_TO_DATE -> getString(R.string.timetable_up_to_date) TimetableDownloader.RESULT_FINISHED -> getString(R.string.timetable_downloaded) else -> getString(R.string.error_try_later) diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt index af652ab3dad6fec82a7bb93d85733aac2cc10f56..51f7ceb59d2c1d06b955e977950e04c463317fe8 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt @@ -24,7 +24,7 @@ } } suspend fun getSheds(name: String): Map<String, Set<String>> { - val response = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""") + val (_, response) = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""") if (!response.has("success")) return emptyMap() val rootObject = response["success"].asJsonObject["bollards"].asJsonArray @@ -55,7 +55,7 @@ }.toSet() }*/ suspend fun getStops(pattern: String): List<StopSuggestion> { - val response = withContext(DefaultDispatcher) { + val (_, response) = withContext(DefaultDispatcher) { makeRequest("getStopPoints", """{"pattern": "$pattern"}""") } @@ -74,9 +74,9 @@ return names.map { StopSuggestion(it, "", "") } } - suspend fun makeRequest(method: String, data: String): JsonObject { + suspend fun makeRequest(method: String, data: String): Pair<Int, JsonObject> { if (!NetworkStateReceiver.isNetworkAvailable()) - return JsonObject() + return Pair(0, JsonObject()) val client = OkHttpClient() val url = "http://www.peka.poznan.pl/vm/method.vm?ts=${Calendar.getInstance().timeInMillis}" @@ -88,24 +88,28 @@ .post(body) .build() - val responseBody: String? + var responseBody: String? = null + var responseCode = 0 try { - responseBody = withContext(CommonPool) { - client.newCall(request).execute().body()?.string() + withContext(CommonPool) { + client.newCall(request).execute().let { + responseCode = it.code() + responseBody = it.body()?.string() + } } } catch (e: IOException) { - return JsonObject() + return Pair(0, JsonObject()) } return try { - Gson().fromJson(responseBody, JsonObject::class.java) + Pair(responseCode, Gson().fromJson(responseBody, JsonObject::class.java)) } catch (e: JsonSyntaxException) { - JsonObject() + Pair(responseCode, JsonObject()) } } suspend fun getName(symbol: String): String? { - val timesResponse = withContext(DefaultDispatcher) { + val (_, timesResponse) = withContext(DefaultDispatcher) { makeRequest("getTimes", """{"symbol": "$symbol"}""") } if (!timesResponse.has("success")) @@ -116,7 +120,7 @@ } suspend fun getDirections(symbol: String): StopSegment? { val name = getName(symbol) - val directionsResponse = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""") + val (_, directionsResponse) = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""") if (!directionsResponse.has("success")) return null diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt index 710aa49f6b3ad7a7f661864ea4231306aa403f20..9dfcc25f261319fbca5cad8912d608614a00347b 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt @@ -20,6 +20,7 @@ const val ACTION_READY = "ml.adamsprogs.bimba.action.vm.ready" const val EXTRA_DEPARTURES = "ml.adamsprogs.bimba.extra.vm.departures" const val EXTRA_PLATE_ID = "ml.adamsprogs.bimba.extra.vm.plate" const val EXTRA_STOP_CODE = "ml.adamsprogs.bimba.extra.vm.stop" + const val EXTRA_CODE = "ml.adamsprogs.bimba.extra.vm.code" const val TICK_6_ZINA_TIM = 12500L const val TICK_6_ZINA_TIM_WITH_MARGIN = TICK_6_ZINA_TIM * 3 / 4 } @@ -76,9 +77,10 @@ return START_STICKY } private fun cleanRequests() { - requests.forEach { - if (it.value <= 0) - requests.remove(it.key) + val newRequests = requests.filter { it.value > 0 } + requests.clear() + newRequests.forEach { + requests[it.key] = it.value } } @@ -121,10 +123,10 @@ sendResult(stopCode, null, null) return } - val javaRootMapObject = VmClient.getVmClient().makeRequest("getTimes", """{"symbol": "$stopCode"}""") + val (code, javaRootMapObject) = VmClient.getVmClient().makeRequest("getTimes", """{"symbol": "$stopCode"}""") if (!javaRootMapObject.has("success")) { - sendResult(stopCode, null, null) + sendResult(stopCode, null, null, code) return } @@ -173,12 +175,13 @@ } } - private fun sendResult(stopCode: String, plateId: Plate.ID?, departures: HashSet<Departure>?) { + private fun sendResult(stopCode: String, plateId: Plate.ID?, departures: HashSet<Departure>?, code: Int = 200) { val broadcastIntent = Intent() broadcastIntent.action = ACTION_READY broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT) if (departures != null) broadcastIntent.putStringArrayListExtra(EXTRA_DEPARTURES, departures.map { it.toString() } as ArrayList) + broadcastIntent.putExtra(EXTRA_CODE, code) broadcastIntent.putExtra(EXTRA_PLATE_ID, plateId) broadcastIntent.putExtra(EXTRA_STOP_CODE, stopCode) sendBroadcast(broadcastIntent) diff --git a/app/src/main/java/ml/adamsprogs/bimba/extensions.kt b/app/src/main/java/ml/adamsprogs/bimba/extensions.kt index a349dc85e76661e7745d7245c11cf93a3d450e75..9b51907278628c82c89e90b50b4f7b8c2bc241a9 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/extensions.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/extensions.kt @@ -4,7 +4,9 @@ import android.annotation.SuppressLint import android.content.Context import android.graphics.drawable.Drawable import android.os.Build +import android.support.design.widget.Snackbar import android.text.format.DateFormat +import android.view.View import ml.adamsprogs.bimba.activities.StopActivity import java.io.* import java.text.SimpleDateFormat @@ -126,4 +128,14 @@ val time = timeFormat.format(this.time) "$date, $time" } else date +} + +fun showError(view: View, code: Int, context: Context) { + val message = when { + code == 0 -> context.getString(R.string.no_connectivity) + (code >= 500) and (code < 600) -> context.getString(R.string.server_error) + else -> "" + } + if (message != "") + Snackbar.make(view, message, Snackbar.LENGTH_LONG).show() } \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt index 8e2a99c5f289cabf1caacd451ff3bd91cb26d5d1..da24710bb4eb92c79f3cdb3c77e10394ffe2bf23 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt @@ -145,9 +145,9 @@ listenerId = providerProxy.subscribeForDepartures(segments, this, context) return listenerId } - override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?) { + override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) { cache = departures - listener.onDeparturesReady(departures, plateId) + listener.onDeparturesReady(departures, plateId, code) } fun unsubscribeFromDepartures(context: Context) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b9385f070698ba94c13d54a19aa103dee644cf0b..513e4652283dcb5cd773feefafbc6ce810b49bcd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,7 +18,8 @@Downloading timetable <string name="timetable_downloading_progress" translatable="false">%1$1.2f MiB/%2$1.2f MiB</string> <string name="timetable_decompressing">Decompressing timetable</string> <string name="search_placeholder">Stop…</string> - <string name="no_connectivity">No connectivity – can’t update timetable</string> + <string name="no_connectivity_cant_update">No connectivity – can’t update timetable</string> + <string name="no_connectivity">No connectivity</string> <string name="timetable_up_to_date">Timetable is up-to-date</string> <string name="validity_failed">Downloaded timetable is corrupted – can’t update</string> <string name="error_try_later">Error. Try again later</string> @@ -89,4 +90,5 @@Fri <string name="Sat">Sat</string> <string name="Sun">Sun</string> <string name="summary_timetable_automatic_update">Automatically check for and download timetable updates</string> + <string name="server_error">Server error</string> </resources> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 0d89712827a98db6c34e2a4b7faac7f0647f0956..094229af232761e69b00552d2a3022dca6161e84 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -17,7 +17,8 @@Verbind mit dem Internet, um den Fahrplan herunterzuladen <string name="no_db_downloading">Fahrplan wird heruntergeladen…</string> <string name="timetable_downloading">Fahrplan wird heruntergeladen</string> <string name="search_placeholder">Haltestelle…</string> - <string name="no_connectivity">Kein Verbindung – kann nicht den Fahrplan aktualisieren</string> + <string name="no_connectivity_cant_update">Kein Verbindung – kann nicht den Fahrplan aktualisieren</string> + <string name="no_connectivity">Kein Verbindung</string> <string name="timetable_up_to_date">Fahrplan ist aktuell</string> <string name="validity_failed">Der heruntergeladene Fahrplan ist geschädigt – kann nicht aktualisieren</string> <string name="error_try_later">Fehler. Versuch später noch einmal</string> @@ -70,4 +71,5 @@Sa. <string name="Sun">So.</string> <string name="title_timetable_automatic_update">Automatische Updates</string> <string name="summary_timetable_automatic_update">Automatisch nach Fahrplanaktualisierungen suchen und diese herunterladen</string> + <string name="server_error">Serverfehler</string> </resources> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 16ed32fc1cb98d9bd718d396ff7d53ff47c4d766..2269942ded34a1ddcc980175b7536da1b0b10ede 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -20,7 +20,8 @@Connetti a Internet per scaricare l’orario <string name="no_db_downloading">L’orario è stando scaricato</string> <string name="timetable_downloading">Scaricando l’orario</string> <string name="search_placeholder">Fermata…</string> - <string name="no_connectivity">Nessuna connettività – non si riesce aggiornare l’orario</string> + <string name="no_connectivity_cant_update">Nessuna connettività – non si riesce aggiornare l’orario</string> + <string name="no_connectivity">Nessuna connettività</string> <string name="timetable_up_to_date">L’orario sta aggiornato</string> <string name="validity_failed">L’orario scaricato sta corrotto – non si riesce aggiornare</string> <string name="error_try_later">Errore. Riprova più tardi</string> @@ -69,4 +70,5 @@sab <string name="Sun">dom</string> <string name="summary_timetable_automatic_update">Controlla e scarica automaticamente gli aggiornamenti dell’orario</string> <string name="title_timetable_automatic_update">Aggiornamenti automatici</string> + <string name="server_error">Errore del server</string> </resources> diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b221b994f403382f9f5d11fb7aeb7cd93a3dbf09..e3a00a950c096b82a64501d0a55b6649e1cccce8 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -12,7 +12,8 @@Maak verbinding met internet om de dienstregeling te downloaden. <string name="no_db_downloading">De dienstregeling wordt gedownload…</string> <string name="timetable_downloading">Bezig met downloaden van dienstregeling</string> <string name="search_placeholder">Halte…</string> - <string name="no_connectivity">Geen internetverbinding – de dienstregeling kan niet worden bijgewerkt.</string> + <string name="no_connectivity_cant_update">Geen internetverbinding – de dienstregeling kan niet worden bijgewerkt.</string> + <string name="no_connectivity">Geen internetverbinding</string> <string name="timetable_up_to_date">De dienstregeling is volledig bijgewerkt.</string> <string name="validity_failed">De gedownloade dienstregeling bevat fouten – bijwerken is niet mogelijk.</string> <string name="error_try_later">Fout; probeer het later opnieuw.</string> @@ -71,4 +72,5 @@za <string name="Sun">zo</string> <string name="title_timetable_automatic_update">Automatische updates</string> <string name="summary_timetable_automatic_update">Automatisch controleren en download dienstregeling updates</string> + <string name="server_error">Serverfout</string> </resources> diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b7e12ec5d2b6da0c24c679dab4db23edda1e645b..d627a692c607c5efb7198a47e16ecda5d285f774 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -14,7 +14,8 @@Pobieranie rozkładu <string name="search_placeholder">Przystanek…</string> <string name="timetable_up_to_date">Rozkład jest aktualny</string> <string name="validity_failed">Pobrany rozkład jest uszkodzony – nie można zaktualizować</string> - <string name="no_connectivity">Brak połączenia z Internetem – nie można zaktualizować rozkładu</string> + <string name="no_connectivity_cant_update">Brak połączenia z Internetem – nie można zaktualizować rozkładu</string> + <string name="no_connectivity">Brak połączenia z Internetem</string> <string name="error_try_later">Błąd. Spróbuj ponownie później</string> <string name="now">Teraz</string> <string name="stop_already_fav">Ten przystanek już jest pośród ulubionych</string> @@ -70,4 +71,5 @@sob. <string name="Sun">niedz.</string> <string name="summary_timetable_automatic_update">Automatycznie sprawdzaj i pobieraj aktualizacje rozkładu</string> <string name="title_timetable_automatic_update">Automatyczne aktualizacje</string> + <string name="server_error">Błąd servera</string> </resources> \ No newline at end of file diff --git a/build.gradle b/build.gradle index 9dd962ea072e40838a705c23178e0f7c41df1161..46a60aa5ed0c08de693c8ed41f436fa47d145972 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.61' + ext.kotlin_version = '1.2.70' repositories { jcenter() maven { url 'https://maven.google.com' }