Error Handler
This commit is contained in:
parent
be950a83da
commit
085ea807c9
@ -63,4 +63,5 @@ dependencies {
|
||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package id.ac.ubharajaya.sistemakademik
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Lock
|
||||
import androidx.compose.material.icons.filled.Warning
|
||||
import androidx.compose.material.icons.filled.WifiOff
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
// 1. Tampilan Error Full Screen (Misal saat gagal load list)
|
||||
@Composable
|
||||
fun FullScreenErrorState(
|
||||
message: String,
|
||||
onRetry: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.fillMaxSize().padding(32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Icon(
|
||||
imageVector = if (message.contains("internet")) Icons.Default.WifiOff else Icons.Default.Warning,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(64.dp),
|
||||
tint = MaterialTheme.colorScheme.error
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = "Ups, Terjadi Masalah",
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = message,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Button(onClick = onRetry) {
|
||||
Text("Coba Lagi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Dialog Error (Misal saat gagal submit absen)
|
||||
@Composable
|
||||
fun ErrorDialog(
|
||||
message: String,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text("Gagal") },
|
||||
text = { Text(message) },
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("OK")
|
||||
}
|
||||
},
|
||||
icon = {
|
||||
Icon(Icons.Default.Warning, contentDescription = null, tint = MaterialTheme.colorScheme.error)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 3. Session Expired Dialog (Khusus Logout)
|
||||
@Composable
|
||||
fun SessionExpiredDialog(
|
||||
onConfirm: () -> Unit
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {}, // Tidak bisa dicancel
|
||||
title = { Text("Sesi Berakhir") },
|
||||
text = { Text("Token akses Anda sudah kadaluarsa. Silakan login kembali untuk melanjutkan.") },
|
||||
confirmButton = {
|
||||
Button(onClick = onConfirm) {
|
||||
Text("Login Ulang")
|
||||
}
|
||||
},
|
||||
icon = {
|
||||
Icon(Icons.Default.Lock, contentDescription = null)
|
||||
}
|
||||
)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,43 @@
|
||||
package id.ac.ubharajaya.sistemakademik
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.net.ConnectException
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
|
||||
object ErrorHandler {
|
||||
|
||||
// Menerjemahkan Exception Java ke Pesan Manusia
|
||||
fun parseException(e: Exception): String {
|
||||
return when (e) {
|
||||
is UnknownHostException -> "🚫 Tidak ada koneksi internet. Periksa wifi/data Anda."
|
||||
is SocketTimeoutException -> "⏳ Waktu habis. Server tidak merespons (Timeout)."
|
||||
is ConnectException -> "🔌 Gagal terhubung ke server. Server mungkin sedang offline."
|
||||
else -> "⚠️ Terjadi kesalahan: ${e.message}"
|
||||
}
|
||||
}
|
||||
|
||||
// Menerjemahkan Response Code HTTP
|
||||
fun parseHttpError(responseCode: Int, errorBody: String): String {
|
||||
// Coba ambil pesan error spesifik dari JSON server (jika ada)
|
||||
val serverMessage = try {
|
||||
val json = JSONObject(errorBody)
|
||||
json.optString("error", "")
|
||||
} catch (e: Exception) {
|
||||
""
|
||||
}
|
||||
|
||||
if (serverMessage.isNotEmpty()) return serverMessage
|
||||
|
||||
// Jika tidak ada pesan JSON, gunakan pesan default berdasarkan kode
|
||||
return when (responseCode) {
|
||||
400 -> "❌ Permintaan tidak valid (Bad Request)."
|
||||
401 -> "🔒 Sesi telah berakhir. Silakan login kembali."
|
||||
403 -> "⛔ Anda tidak memiliki akses ke fitur ini."
|
||||
404 -> "🔍 Data atau alamat tidak ditemukan."
|
||||
500 -> "🔥 Terjadi kesalahan internal pada server."
|
||||
502, 503 -> "🚧 Server sedang dalam perbaikan (Maintenance)."
|
||||
else -> "⚠️ Terjadi kesalahan (Kode: $responseCode)."
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user