EAS-202310715274-DimasHendr.../HISTORY_SCREEN_FIX.md
2026-01-14 21:13:18 +07:00

3.6 KiB

Fix: History Screen Close App Issue

📋 Problem Identified

Issue: App crash ketika membuka riwayat absensi (History Screen)

Root Causes:

  1. Missing null/empty string checks - Field seperti nama, npm, mataPelajaran, message dapat kosong atau null, menyebabkan rendering error
  2. No exception handling - Tidak ada try-catch wrapper di AttendanceCard composable
  3. Date formatting error - dateFormatter.format() bisa throw exception jika timestamp invalid

🔧 Solutions Applied

1. Wrapped AttendanceCard dengan Try-Catch

@Composable
fun AttendanceCard(
    attendance: Attendance,
    dateFormatter: SimpleDateFormat
) {
    try {
        // ... semua logika rendering ...
    } catch (e: Exception) {
        // Fallback UI menampilkan error message
        Card(
            modifier = Modifier.fillMaxWidth(),
            colors = CardDefaults.cardColors(
                containerColor = MaterialTheme.colorScheme.errorContainer
            )
        ) {
            Column(...) {
                Text("Error menampilkan data absensi")
                Text(e.message ?: "Unknown error")
            }
        }
    }
}

2. Added Null/Empty Safety Checks

// Sebelum:
Text(text = attendance.nama)  // ❌ Crash jika kosong

// Sesudah:
Text(text = attendance.nama.takeIf { it.isNotEmpty() } ?: "N/A")  // ✅ Safe
Text(text = attendance.mataPelajaran.takeIf { it.isNotEmpty() } ?: "-")  // ✅ Safe
Text(text = attendance.npm.takeIf { it.isNotEmpty() } ?: "N/A")  // ✅ Safe

3. Protected Date Formatting

// Sebelum:
Text(text = "📅 ${dateFormatter.format(Date(attendance.timestamp))}")  // ❌ Can crash

// Sesudah:
try {
    Text(text = "📅 ${dateFormatter.format(Date(attendance.timestamp))}")
} catch (e: Exception) {
    Text(text = "📅 ${attendance.timestamp}")  // Fallback ke raw timestamp
}

4. Protected Distance Calculation

val (distanceFromCampus, isWithinRadius) = try {
    if (attendance.latitude.isFinite() && attendance.longitude.isFinite()) {
        val distance = calculateDistance(...)
        Pair(distance, distance <= AppConfig.ATTENDANCE_RADIUS_METERS)
    } else {
        Pair(0f, false)
    }
} catch (e: Exception) {
    Pair(0f, false)
}

Improvements

Aspek Sebelum Sesudah
Null Safety No checks All fields safe
Exception Handling None Try-catch with fallback
Empty String Handling Crashes Shows "-" or "N/A"
Error Display Crash Error card shown
Stability Unstable Stable

🧪 Test Cases

Test 1: View History dengan Data Valid

1. Buka AttendanceScreen
2. Submit absensi dengan lengkap
3. Buka History
✅ Expected: Riwayat ditampilkan dengan sempurna

Test 2: View History dengan Data Kosong

1. Buka History (tanpa submit apapun)
✅ Expected: Tampilkan "Belum ada riwayat kehadiran"

Test 3: View History dengan Data Partial

1. Submit absensi dengan mataPelajaran kosong
2. Buka History
✅ Expected: Tampilkan "-" untuk mata kuliah, tidak crash

Test 4: Multiple Records

1. Submit 5 kali
2. Buka History
✅ Expected: Semua 5 record ditampilkan, sorted by timestamp DESC

📝 Files Modified

  • presentation/screens/HistoryScreen.kt - Added comprehensive error handling

🚀 Expected Result

App tidak lagi crash ketika membuka History Screen Menampilkan error message yang user-friendly jika ada data issue Graceful fallback untuk berbagai edge cases