I have already looked up some previous questions here in stack overflow but have not found suitable answers for this issue i am new to android dev so i was like playing around with retrofit and as i stated it works fine when i am online however when i turn internet off the query fails and the app crashes (it is not caught in the exception which i have implemented) and logcat does not give me a stack trace to debug (there are no filters in logcat) it simply says fatal exception
this is the code :
@Composable
fun api_call_screen(navController: NavController){
var todos by rememberSaveable { mutableStateOf<List<todos>>(emptyList()) }
var loading by rememberSaveable { mutableStateOf<Boolean>(true) }
var error by rememberSaveable { mutableStateOf<String?>(null) }
LaunchedEffect(Unit) {
val todosresponse =RetrofitInstance.api.gettodo()
val data =try {
if(todosresponse.isSuccessful() && todosresponse.body() != null){
todos =todosresponse.body() ?: emptyList()
Log.e("Api_CALL","Empty List")
}else{
todos=emptyList()
error="Something went wrong"
}
}
catch (e : Exception){
error="Something went wrong"
todos=emptyList()
}
finally {
loading=false
}
}
Box(modifier = Modifier.fillMaxSize()){
if(loading){
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
}else if(error !=null){
Text("$error", modifier = Modifier.align(Alignment.Center))
}
else if (todos==emptyList<todos>()){
Text("No Data", modifier = Modifier.align(Alignment.Center))
}
else{
LazyColumn {
items(items = todos){
todo ->Text(todo.title, modifier = Modifier.padding(16.dp))
}
}
}
}
}
i have not implemented any network checks since i have read the docs and have seen that a IOException would be thrown just confused why it si not caught is there some other error that is happening outside the scope that is caught ? i have no idea kindly help me figure it out and thanks in advance :)
i have also setup the necessary permissions in android manifest file :
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
You need to wrap the entire Retrofit call inside the try-catch
. Retrofit throws IOException when the device is offline or the server is unreachable.
LaunchedEffect(Unit) {
try {
val todosresponse = RetrofitInstance.api.gettodo()
if (todosresponse.isSuccessful && todosresponse.body() != null) {
todos = todosresponse.body() ?: emptyList()
Log.e("Api_CALL", "Got data")
} else {
todos = emptyList()
error = "Server Error: ${todosresponse.code()}"
}
} catch (e: IOException) {
// Network error like no internet
error = "No internet connection."
todos = emptyList()
Log.e("NetworkError", "IOException: ${e.localizedMessage}")
} catch (e: Exception) {
// Other unexpected errors
error = "Unexpected error occurred."
todos = emptyList()
Log.e("UnknownError", "Exception: ${e.localizedMessage}")
} finally {
loading = false
}
}
and
Don’t compare lists like if (todos == emptyList<todos>())
Instead, use .isEmpty():
else if (todos.isEmpty())
{
Text("No Data", modifier = Modifier.align(Alignment.Center))
}