fix: prevent app crash by not parsing non-json responses

This commit is contained in:
2024-08-24 14:17:51 +02:00
parent 2063673a0d
commit 8bbd3bd52b
5 changed files with 31 additions and 11 deletions
@@ -10,6 +10,7 @@ import com.illusionman1212.lyricsgrabbr.utils.await
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import okio.IOException
import org.jsoup.SerializationException
import java.net.SocketTimeoutException
@Serializable
@@ -31,7 +32,7 @@ class HomeRepository(private val context: Context) {
return pkgs.contains(packageName)
}
suspend fun makeSearchRequest(song: String, artist: String): Pair<String?, Boolean> {
suspend fun makeSearchRequest(lContext: Context, song: String, artist: String): Pair<String?, Boolean> {
val builder = Uri.Builder()
val url = builder.scheme("https")
.authority("api.illusionman1212.com")
@@ -47,11 +48,23 @@ class HomeRepository(private val context: Context) {
).await()
if (!res.isSuccessful) {
val errRes = json.decodeFromString(ErrorResponse.serializer(), res.body!!.string())
if (res.code >= 500) {
return Pair(lContext.resources.getString(R.string.internal_server_error), false)
}
// matches is only null if there's an error. otherwise it's 0 when there are no results
if (errRes.matches == null) {
return Pair(context.resources.getString(R.string.generic_error), false)
if (res.body?.contentType()?.type != "text" && res.body?.contentType()?.subtype != "json") {
return Pair(lContext.resources.getString(R.string.invalid_json), false)
}
try {
val errRes = json.decodeFromString(ErrorResponse.serializer(), res.body!!.string())
// matches is only null if there's an error. otherwise it's 0 when there are no results
if (errRes.matches == null) {
return Pair(lContext.resources.getString(R.string.generic_error), false)
}
} catch (e: IllegalArgumentException) {
return Pair(lContext.resources.getString(R.string.failed_to_map_json), false)
}
return Pair(null, false)
@@ -60,10 +73,10 @@ class HomeRepository(private val context: Context) {
return Pair(res.body?.string(), true)
} catch (e: IOException) {
if (e.cause is SocketTimeoutException) {
return Pair(context.resources.getString(R.string.timeout), false)
return Pair(lContext.resources.getString(R.string.timeout), false)
}
return Pair(context.resources.getString(R.string.generic_error), false)
return Pair(lContext.resources.getString(R.string.generic_error), false)
}
}
}
@@ -155,7 +155,7 @@ fun HomePage(
if (song != null && song.title != uiState.notification?.title && song.artist != uiState.notification?.artist) {
homeViewModel.setSong(song)
homeViewModel.makeRequestToGenius(song.title, song.artist)
homeViewModel.makeRequestToGenius(context, song.title, song.artist)
}
}
@@ -305,7 +305,7 @@ fun HomePage(
)
FilledTonalButton(
onClick = {
homeViewModel.makeRequestToGenius(song.title, song.artist)
homeViewModel.makeRequestToGenius(context, song.title, song.artist)
}
) {
Text(stringResource(id = R.string.retry))
@@ -1,5 +1,6 @@
package com.illusionman1212.lyricsgrabbr.viewmodels
import android.content.Context
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
@@ -101,12 +102,12 @@ class HomeViewModel(private val homeRepository: HomeRepository): ViewModel() {
}
}
fun makeRequestToGenius(song: String, artist: String) {
fun makeRequestToGenius(context: Context, song: String, artist: String) {
viewModelScope.launch {
_uiState.update { HomeState(true, uiState.value.results, uiState.value.notification, null) }
withContext(Dispatchers.IO) {
val (res, isSuccess) = homeRepository.makeSearchRequest(song, artist)
val (res, isSuccess) = homeRepository.makeSearchRequest(context, song, artist)
if (isSuccess) {
val results = json.decodeFromString(SearchResultsResponse.serializer(), res!!).all.map {
SearchResult(
+3
View File
@@ -7,6 +7,9 @@
<string name="cancel">إلغاء</string>
<string name="timeout">لقد انتهت مهلة الطلب، حاول مرة أخرى لاحقًا</string>
<string name="generic_error">لقد حدث خطأ، حاول مرة أخرى لاحقاً</string>
<string name="internal_server_error">تأكد من تشغيل خادم geniURL الخاص بك إذا كنت تستضيف ذاتيًا أو اتصل بمضيفك.</string>
<string name="invalid_json">الاستجابة لم تكن JSON صالحة</string>
<string name="failed_to_map_json">فشل تعيين JSON المفكك إلى النوع الداخلي</string>
<string name="retry">أعد المحاولة</string>
<!-- Home -->
+3
View File
@@ -6,6 +6,9 @@
<string name="cancel">Cancel</string>
<string name="timeout">Request has timed out, try again later</string>
<string name="generic_error">An error has occurred, try again later</string>
<string name="internal_server_error">Internal server error. Make sure your geniURL server is running if self-hosting or contact your hoster.</string>
<string name="invalid_json">Response was not valid JSON</string>
<string name="failed_to_map_json">Failed to map decoded JSON to internal type.</string>
<string name="retry">Retry</string>
<!-- Home -->