From 2973325428df3815a1dbf148e933014b7e104a06 Mon Sep 17 00:00:00 2001 From: private-yusuke <30387586+private-yusuke@users.noreply.github.com> Date: Thu, 18 Apr 2024 14:11:13 +0900 Subject: [PATCH] Handle `java.lang.IOException` with network requests by `TwinteBackendHttpClien t` --- .../java/net/twinte/android/MainActivity.kt | 37 +++++++++++++------ .../SharedPreferencesScheduleDataStore.kt | 28 ++++++++------ .../android/widget/V3LargeWidgetProvider.kt | 5 ++- .../android/widget/V3MediumWidgetProvider.kt | 5 ++- 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/net/twinte/android/MainActivity.kt b/app/src/main/java/net/twinte/android/MainActivity.kt index 2e92c12..01be25c 100644 --- a/app/src/main/java/net/twinte/android/MainActivity.kt +++ b/app/src/main/java/net/twinte/android/MainActivity.kt @@ -11,6 +11,7 @@ import android.webkit.ValueCallback import android.webkit.WebChromeClient import android.webkit.WebResourceRequest import android.webkit.WebView +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.webkit.WebSettingsCompat @@ -72,13 +73,17 @@ class MainActivity : AppCompatActivity(), SubWebViewFragment.Callback { UpdateScheduleWorker.scheduleNextUpdate(workManager) scheduleNotificationDataStore.schedule() GlobalScope.launch { - try { - scheduleDataStore.update() - } catch (e: NotLoggedInException) { - // 未ログイン時は失敗するが何もしない - } catch (e: Exception) { - // それ以外の予期せぬエラー - } + kotlin.runCatching { scheduleDataStore.update() } + .fold(onSuccess = {}, onFailure = { + when (it) { + is NotLoggedInException -> { + // 未ログイン時は失敗するが何もしない + } + else -> { + // それ以外の予期せぬエラー + } + } + }) WidgetUpdater.updateAllWidget(this@MainActivity) WidgetUpdater.scheduleAllIfExists(this@MainActivity) } @@ -197,7 +202,10 @@ class MainActivity : AppCompatActivity(), SubWebViewFragment.Callback { val account = GoogleSignIn.getSignedInAccountFromIntent(data).result GlobalScope.launch { account?.idToken?.let { - userDataStore.validateGoogleIdToken(it) + kotlin.runCatching { userDataStore.validateGoogleIdToken(it) } + .onFailure { + Toast.makeText(applicationContext, R.string.common_google_play_services_unknown_issue, Toast.LENGTH_SHORT).show() + } } withContext(Dispatchers.Main) { binding.mainWebview.loadUrl(twinteUrlBuilder(serverSettings).buildUrl()) @@ -219,11 +227,16 @@ class MainActivity : AppCompatActivity(), SubWebViewFragment.Callback { super.onPause() cookieManager.flush() GlobalScope.launch { - try { + kotlin.runCatching { scheduleDataStore.update() - } catch (e: NotLoggedInException) { - // 未ログイン時は失敗するが何もしない - } + }.fold(onSuccess = {}, onFailure = { e -> + when (e) { + is NotLoggedInException -> { + // 未ログイン時は失敗するが何もしない + } + else -> { } + } + }) WidgetUpdater.updateAllWidget(this@MainActivity) } } diff --git a/app/src/main/java/net/twinte/android/datastore/schedule/SharedPreferencesScheduleDataStore.kt b/app/src/main/java/net/twinte/android/datastore/schedule/SharedPreferencesScheduleDataStore.kt index 5e9ad09..68ad6eb 100644 --- a/app/src/main/java/net/twinte/android/datastore/schedule/SharedPreferencesScheduleDataStore.kt +++ b/app/src/main/java/net/twinte/android/datastore/schedule/SharedPreferencesScheduleDataStore.kt @@ -26,18 +26,22 @@ class SharedPreferencesScheduleDataStore @Inject constructor( with(pref.edit()) { clear() calendar.map { simpleDateFormat.format(it) }.forEach { d -> - val res = twinteBackendHttpClient.get("/api/v3/timetable/$d") - - if (!res.isSuccessful) { - if (res.code == 401) { - throw NotLoggedInException() - } else { - throw IOException("API call failed with code ${res.code}\n ${res.body?.string()}") - } - } - putString(d, res.body?.string()) - // TODO: replace `android.util.Log` with Timber - // Log.d(TAG, "schedule updated $d $res") + kotlin.runCatching { twinteBackendHttpClient.get("/api/v3/timetable/$d") } + .fold(onSuccess = { + if (!it.isSuccessful) { + if (it.code == 401) { + throw NotLoggedInException() + } else { + throw IOException("API call failed with code ${it.code}\n ${it.body.string()}") + } + } + putString(d, it.body.string()) + }, onFailure = { + if (it !is IOException) { + throw it + } + return@withContext + }) } commit() } diff --git a/app/src/main/java/net/twinte/android/widget/V3LargeWidgetProvider.kt b/app/src/main/java/net/twinte/android/widget/V3LargeWidgetProvider.kt index 17bcade..036e458 100644 --- a/app/src/main/java/net/twinte/android/widget/V3LargeWidgetProvider.kt +++ b/app/src/main/java/net/twinte/android/widget/V3LargeWidgetProvider.kt @@ -139,10 +139,11 @@ class V3LargeWidgetRemoteViewService @Inject constructor() : RemoteViewsService( override fun onCreate() {} - override fun onDataSetChanged() = runBlocking { + override fun onDataSetChanged(): Unit = runBlocking { Log.d("LargeFactory", "onDataSetChanged") val (current, _) = WidgetUpdater.getShouldShowCurrentDate() - schedule = scheduleDataStore.getSchedule(current.time) + kotlin.runCatching { scheduleDataStore.getSchedule(current.time) } + .onSuccess { schedule = it } } override fun onDestroy() {} diff --git a/app/src/main/java/net/twinte/android/widget/V3MediumWidgetProvider.kt b/app/src/main/java/net/twinte/android/widget/V3MediumWidgetProvider.kt index 49142c4..f3c9463 100644 --- a/app/src/main/java/net/twinte/android/widget/V3MediumWidgetProvider.kt +++ b/app/src/main/java/net/twinte/android/widget/V3MediumWidgetProvider.kt @@ -138,10 +138,11 @@ class V3MediumWidgetRemoteViewService @Inject constructor() : RemoteViewsService override fun onCreate() {} - override fun onDataSetChanged() = runBlocking { + override fun onDataSetChanged(): Unit = runBlocking { Log.d("MediumFactory", "onDataSetChanged") val (current, _) = WidgetUpdater.getShouldShowCurrentDate() - schedule = scheduleDataStore.getSchedule(current.time) + kotlin.runCatching { scheduleDataStore.getSchedule(current.time) } + .onSuccess { schedule = it } } override fun onDestroy() {}