From 8bbd3bd52b2368f0eb120c84fdd0bff17c0107fd Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Sat, 24 Aug 2024 14:17:51 +0200 Subject: [PATCH] fix: prevent app crash by not parsing non-json responses --- .../lyricsgrabbr/data/HomeRepository.kt | 27 ++++++++++++++----- .../lyricsgrabbr/ui/screens/Home.kt | 4 +-- .../lyricsgrabbr/viewmodels/HomeViewModel.kt | 5 ++-- app/src/main/res/values-ar/strings.xml | 3 +++ app/src/main/res/values/strings.xml | 3 +++ 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/illusionman1212/lyricsgrabbr/data/HomeRepository.kt b/app/src/main/java/com/illusionman1212/lyricsgrabbr/data/HomeRepository.kt index 41d907a..4049570 100644 --- a/app/src/main/java/com/illusionman1212/lyricsgrabbr/data/HomeRepository.kt +++ b/app/src/main/java/com/illusionman1212/lyricsgrabbr/data/HomeRepository.kt @@ -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 { + suspend fun makeSearchRequest(lContext: Context, song: String, artist: String): Pair { 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) } } } \ No newline at end of file diff --git a/app/src/main/java/com/illusionman1212/lyricsgrabbr/ui/screens/Home.kt b/app/src/main/java/com/illusionman1212/lyricsgrabbr/ui/screens/Home.kt index 3fb9777..9c47fb2 100644 --- a/app/src/main/java/com/illusionman1212/lyricsgrabbr/ui/screens/Home.kt +++ b/app/src/main/java/com/illusionman1212/lyricsgrabbr/ui/screens/Home.kt @@ -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)) diff --git a/app/src/main/java/com/illusionman1212/lyricsgrabbr/viewmodels/HomeViewModel.kt b/app/src/main/java/com/illusionman1212/lyricsgrabbr/viewmodels/HomeViewModel.kt index 89acf39..6f9c0a1 100644 --- a/app/src/main/java/com/illusionman1212/lyricsgrabbr/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/com/illusionman1212/lyricsgrabbr/viewmodels/HomeViewModel.kt @@ -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( diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2058612..03dc0dd 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -7,6 +7,9 @@ إلغاء لقد انتهت مهلة الطلب، حاول مرة أخرى لاحقًا لقد حدث خطأ، حاول مرة أخرى لاحقاً + تأكد من تشغيل خادم geniURL الخاص بك إذا كنت تستضيف ذاتيًا أو اتصل بمضيفك. + الاستجابة لم تكن JSON صالحة + فشل تعيين JSON المفكك إلى النوع الداخلي أعد المحاولة diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a737d5c..f104cbf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,6 +6,9 @@ Cancel Request has timed out, try again later An error has occurred, try again later + Internal server error. Make sure your geniURL server is running if self-hosting or contact your hoster. + Response was not valid JSON + Failed to map decoded JSON to internal type. Retry