Setiap programmer Kotlin pasti berpapasan dengan pesan kesalahan — baik dari kompilator maupun dari runtime. Pada chapter ini kita akan membedah anatomi pesan error kotlinc, mengurai format file:line:col hingga penanda caret, lalu belajar membaca stack trace saat runtime. Dengan memahami pola pesan kesalahan, kita dapat mempercepat siklus edit-kompilasi-jalankan dan menemukan akar masalah tanpa menebak-nebak.
Anatomi Pesan Error Kompilator #
Kompilator kotlinc mengeluarkan pesan kesalahan dalam format yang konsisten. Berikut cuplikan kode sengaja dibuat salah dengan type mismatch:
fun main() {
val umur: Int = "dua puluh lima"
println("Umur: $umur")
}Saat dikompilasi, kotlinc mengeluarkan pesan berikut:
error.kt:2:21: error: initializer type mismatch: expected 'kotlin.Int', actual 'kotlin.String'.
val umur: Int = "dua puluh lima"
^^^^^^^^^^^^^^^^Mari kita bedah bagian-bagian pesan di atas:
error.kt:2:21— lokasi kesalahan: fileerror.kt, baris ke-2, kolom ke-21. Kolom dihitung mulai dari 1 di awal baris.error:— tingkat keparahan. Kompilator Kotlin juga memancarkanwarning:untuk hal yang tidak fatal.initializer type mismatch: expected 'kotlin.Int', actual 'kotlin.String'.— deskripsi kesalahan. Pesan ini menyatakan bahwa tipe initializer (String) tidak cocok dengan tipe yang dideklarasikan (Int).- Baris kode yang ditampilkan ulang — kompilator menyalin baris yang bermasalah agar pembaca tidak perlu bergulir ke file.
^^^^^^^^^^^^^^^^— caret menunjuk persis token yang menjadi sumber kesalahan. Panjang caret sesuai dengan panjang token"dua puluh lima".
Tiga Sumber Kesalahan Kompilator #
Pesan error kotlinc umumnya jatuh pada tiga kategori:
| Kategori | Contoh pesan | Penyebab umum |
|---|---|---|
| Type mismatch | expected 'kotlin.Int', actual 'kotlin.String' | Variabel diisi nilai dengan tipe berbeda |
| Unresolved reference | unresolved reference: namaVariabel | Salah ketik nama; lupa import |
| Type inference failure | type mismatch: inferred type is X but Y was expected | Lambda atau return type tidak konsisten |
| Modifier conflict | 'final' member cannot be overridden | Mencoba override method final |
Setiap kategori punya pola perbaikan berbeda. Type mismatch diselesaikan dengan mengubah tipe atau nilai; unresolved reference diselesaikan dengan import atau memperbaiki ejaan.
Membaca file:line:col #
Lokasi file:line:col adalah informasi paling penting saat menelusuri kesalahan. Mari kita pecah satu contoh:
path/ke/file.kt:13:7
^^^^^^^^^^^^^^^^ ^^^ ^^
| | |
nama file | |
baris |
kolom- Baris dimulai dari 1.
- Kolom dimulai dari 1, dihitung sebagai posisi karakter dari awal baris (termasuk spasi dan tab).
- Beberapa editor seperti IntelliJ IDEA dapat melompat langsung ke lokasi ini saat kita mengklik pesan error.
Caret Menunjuk Sumber Masalah #
Caret (^^^^^^) di bawah baris kode menandai persis token yang menjadi sumber kesalahan. Perhatikan contoh berikut:
error.kt:2:21: error: initializer type mismatch: expected 'kotlin.Int', actual 'kotlin.String'.
val umur: Int = "dua puluh lima"
^^^^^^^^^^^^^^^^Caret hanya menutupi literal string "dua puluh lima", bukan seluruh baris. Ini memberi tahu kita bahwa masalahnya ada pada literal string, bukan pada deklarasi val umur: Int. Solusinya jelas: ganti literal string dengan literal integer seperti 25, atau ubah tipe variabel menjadi String.
Stack Trace saat Runtime #
Kesalahan yang lolos dari kompilasi muncul saat runtime sebagai exception. Berikut program sengaja memicu IndexOutOfBoundsException dan menangkap jejak tumpukan (stack trace):
fun main() {
val daftar = listOf("Budi", "Siti", "Andi")
println("Daftar peserta: $daftar")
try {
val indeks = 5
val nama = daftar[indeks]
println("Peserta ke-$indeks: $nama")
} catch (e: IndexOutOfBoundsException) {
println("Terjadi kesalahan: ${e::class.simpleName}")
println("Pesan: ${e.message}")
println("Jejak tumpukan (3 baris pertama):")
e.stackTrace.take(3).forEach { elem ->
println(" at $elem")
}
}
}Output yang Dihasilkan:
Daftar peserta: [Budi, Siti, Andi]
Terjadi kesalahan: ArrayIndexOutOfBoundsException
Pesan: Index 5 out of bounds for length 3
Jejak tumpukan (3 baris pertama):
at java.base/java.util.Arrays$ArrayList.get(Arrays.java:4266)
at StacktraceKt.main(stacktrace.kt:6)
at StacktraceKt.main(stacktrace.kt)Mari kita bedah output stack trace:
ArrayIndexOutOfBoundsException— nama class exception. Nama ini menyatakan jenis masalah: kita mengakses indeks di luar batas array/list.Index 5 out of bounds for length 3— pesan exception. Pesan ini menyatakan bahwa indeks5di luar batas untuk daftar dengan panjang3.at java.base/java.util.Arrays$ArrayList.get(Arrays.java:4266)— baris pertama stack trace, menunjukkan method internal JDK tempat exception dilempar. Baris ini biasanya bukan akar masalah kita.at StacktraceKt.main(stacktrace.kt:6)— baris kedua menunjukkan kode kita sendiri. Filestacktrace.ktbaris 6 adalah tempat pemanggilandaftar[indeks].at StacktraceKt.main(stacktrace.kt)— baris ketiga adalah wrapper entry point sintetik yang dibuat kompilator Kotlin.
Strategi Membaca Stack Trace #
Saat membaca stack trace, ikuti urutan berikut:
- Baca nama exception dan pesannya — sering kali sudah cukup untuk menebak akar masalah (
NullPointerException,IllegalArgumentException,IndexOutOfBoundsException). - Cari baris yang merujuk ke kode kita sendiri — lewati baris dari
java.base,kotlin.collections, atau library pihak ketiga. Baris dengan nama file kode kita adalah kandidat utama. - Baca baris terdekat dengan akar masalah — stack trace biasanya menampilkan frame paling dalam (tempat exception dilempar) di atas, dan frame pemanggil di bawah. Mulai dari atas, cari frame pertama yang merujuk ke kode kita.
- Telusuri kode di baris tersebut — buka file pada baris yang ditunjuk, periksa nilai variabel lokal dan asumsi yang mungkin salah.
Pesan Error yang Sering Muncul #
Tabel berikut merangkum pesan error yang sering muncul beserta penanganan umum:
| Pesan | Penyebab | Penanganan |
|---|---|---|
unresolved reference: x | Salah ketik atau lupa import | Periksa ejaan; tambahkan import |
type mismatch: inferred type is X but Y was expected | Lambda atau return type tidak konsisten | Sesuaikan tipe parameter atau return |
variable 'x' must be initialized | Variabel val dipakai sebelum diisi | Pindahkan inisialisasi sebelum pemakaian |
null cannot be a value of a non-null type String | Memberi null pada tipe non-nullable | Ubah tipe menjadi String? atau beri nilai non-null |
only safe (?.) or non-null asserted (!!.) calls are allowed | Memanggil method pada nullable tanpa cek null | Pakai ?. atau !! dengan hati-hati |
ArrayIndexOutOfBoundsException | Akses indeks di luar batas | Periksa panjang sebelum akses |
NumberFormatException | Parsing string non-numerik | Validasi input sebelum toInt() |
Referensi Lanjutan #
- Kotlin basic syntax — ringkasan sintaks dasar Kotlin untuk mengenali konteks pesan galat kompilator
- Kotlin command-line compiler — rujukan kompilator CLI yang menerbitkan pesan galat saat kompilasi gagal
Membaca pesan error dengan teliti adalah keterampilan yang berkembang seiring latihan. Setelah memahami anatomi pesan kompilator dan stack trace runtime, kita siap masuk ke materi variabel dan tipe data Kotlin — pembahasan lengkap menanti pada section Variabel dan Tipe Data.