mirror of
https://github.com/IllusionMan1212/lyrics-grabbr.git
synced 2026-10-24 02:12:27 +00:00
fix: prevent app crash by not parsing non-json responses
This commit is contained in:
@@ -10,6 +10,7 @@ import com.illusionman1212.lyricsgrabbr.utils.await
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
|
import org.jsoup.SerializationException
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -31,7 +32,7 @@ class HomeRepository(private val context: Context) {
|
|||||||
return pkgs.contains(packageName)
|
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 builder = Uri.Builder()
|
||||||
val url = builder.scheme("https")
|
val url = builder.scheme("https")
|
||||||
.authority("api.illusionman1212.com")
|
.authority("api.illusionman1212.com")
|
||||||
@@ -47,11 +48,23 @@ class HomeRepository(private val context: Context) {
|
|||||||
).await()
|
).await()
|
||||||
|
|
||||||
if (!res.isSuccessful) {
|
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 (res.body?.contentType()?.type != "text" && res.body?.contentType()?.subtype != "json") {
|
||||||
if (errRes.matches == null) {
|
return Pair(lContext.resources.getString(R.string.invalid_json), false)
|
||||||
return Pair(context.resources.getString(R.string.generic_error), 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)
|
return Pair(null, false)
|
||||||
@@ -60,10 +73,10 @@ class HomeRepository(private val context: Context) {
|
|||||||
return Pair(res.body?.string(), true)
|
return Pair(res.body?.string(), true)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
if (e.cause is SocketTimeoutException) {
|
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) {
|
if (song != null && song.title != uiState.notification?.title && song.artist != uiState.notification?.artist) {
|
||||||
homeViewModel.setSong(song)
|
homeViewModel.setSong(song)
|
||||||
|
|
||||||
homeViewModel.makeRequestToGenius(song.title, song.artist)
|
homeViewModel.makeRequestToGenius(context, song.title, song.artist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ fun HomePage(
|
|||||||
)
|
)
|
||||||
FilledTonalButton(
|
FilledTonalButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
homeViewModel.makeRequestToGenius(song.title, song.artist)
|
homeViewModel.makeRequestToGenius(context, song.title, song.artist)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(stringResource(id = R.string.retry))
|
Text(stringResource(id = R.string.retry))
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.illusionman1212.lyricsgrabbr.viewmodels
|
package com.illusionman1212.lyricsgrabbr.viewmodels
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
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 {
|
viewModelScope.launch {
|
||||||
_uiState.update { HomeState(true, uiState.value.results, uiState.value.notification, null) }
|
_uiState.update { HomeState(true, uiState.value.results, uiState.value.notification, null) }
|
||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val (res, isSuccess) = homeRepository.makeSearchRequest(song, artist)
|
val (res, isSuccess) = homeRepository.makeSearchRequest(context, song, artist)
|
||||||
if (isSuccess) {
|
if (isSuccess) {
|
||||||
val results = json.decodeFromString(SearchResultsResponse.serializer(), res!!).all.map {
|
val results = json.decodeFromString(SearchResultsResponse.serializer(), res!!).all.map {
|
||||||
SearchResult(
|
SearchResult(
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
<string name="cancel">إلغاء</string>
|
<string name="cancel">إلغاء</string>
|
||||||
<string name="timeout">لقد انتهت مهلة الطلب، حاول مرة أخرى لاحقًا</string>
|
<string name="timeout">لقد انتهت مهلة الطلب، حاول مرة أخرى لاحقًا</string>
|
||||||
<string name="generic_error">لقد حدث خطأ، حاول مرة أخرى لاحقاً</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>
|
<string name="retry">أعد المحاولة</string>
|
||||||
|
|
||||||
<!-- Home -->
|
<!-- Home -->
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="timeout">Request has timed out, try again later</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="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>
|
<string name="retry">Retry</string>
|
||||||
|
|
||||||
<!-- Home -->
|
<!-- Home -->
|
||||||
|
|||||||
Reference in New Issue
Block a user