10. Membaca pesan error

Saat sebuah program salah, Go tidak diam saja — Go mencetak sebuah pesan error dan menolak menjalankan program. Pemula melihat teks itu sebagai kebisingan yang menakutkan dan mulai mengubah hal-hal secara acak. Tapi itu bukan kebisingan: Go sedang memberitahumu tepat di baris mana yang harus dilihat dan memberikan petunjuk apa yang salah. Bab ini mengajarkan cara membacanya.

Bentuk sebuah error

Go menemukan kesalahan-kesalahan ini saat mengompilasi, sebelum bagian mana pun dari programmu berjalan. Itulah sebabnya program dengan satu kesalahan di baris terakhirnya tidak mencetak apa pun, bahkan output dari baris-baris di atasnya.

Hampir setiap error kompilasi Go punya bentuk yang sama:

# command-line-arguments
file:line:column: message

Tiga bagian, dan kamu membacanya dalam urutan ini:

  1. Nama file dan nomor baris (.\hello.go:6). Lihat di situ dulu. Selalu. Tanda .\ di depan berarti "di folder ini".
  2. Kolom (18), seberapa jauh di baris itu Go menyadari masalahnya, dihitung per karakter dari kiri. Tab dihitung satu karakter.
  3. Pesan — deskripsi singkat tentang apa yang salah.

Baris # command-line-arguments di bagian atas hanya menyatakan bahwa Go sedang mengompilasi file yang kamu sebutkan. Baris itu belum penting untuk sekarang. Go juga tidak mengutip kodemu, jadi buka file-nya dan pergi ke baris itu.

Empat error yang paling sering kamu temui

Keempat ini mencakup sebagian besar kesalahan awal. Belajar mengenalinya dari pandangan pertama. Untuk setiap error, bayangkan ini adalah hello.go di folder go-work kamu, dijalankan dengan go run hello.go.

newline in string

Kamu lupa tanda kutip penutup.

package main

import "fmt"

func main() {
    fmt.Println("hi)
}
# command-line-arguments
.\hello.go:6:18: newline in string
.\hello.go:6:18: syntax error: unexpected newline in argument list; possibly missing comma or )

"Newline in string" berarti Go menemukan tanda kutip pembuka dan mencapai akhir baris tanpa menemukan penutupnya. Kolom 18 adalah akhir baris, tempat Go menyerah. Baris kedua adalah akibat dari baris pertama, jadi hanya ada satu hal yang perlu diperbaiki: tambahkan " yang hilang sebelum ).

undefined: name

Kamu salah mengeja sebuah nama.

package main

import "fmt"

func main() {
    fmt.Prinln("hi")
}
# command-line-arguments
.\hello.go:6:6: undefined: fmt.Prinln

Go berkata: kamu menggunakan nama fmt.Prinln, tapi tidak ada yang bernama itu. Nama setelah undefined: adalah kata yang salah eja. Perbaikan: tulis fmt.Println.

Pesan yang sama muncul untuk nama tanpa fmt. di depannya, dan kesalahan itu bisa menimbulkan error kedua:

package main

import "fmt"

func main() {
    prnt("hi")
}
# command-line-arguments
.\hello.go:3:8: "fmt" imported and not used
.\hello.go:6:2: undefined: prnt

Go mencantumkan error menurut urutan baris, bukan menurut tingkat kepentingan. Kesalahan sebenarnya ada di baris 6. Begitu baris itu menjadi fmt.Println, fmt terpakai lagi dan kedua error hilang.

imported and not used, declared and not used

Kamu memasukkan sesuatu ke dalam program dan tidak pernah memakainya. Banyak bahasa membiarkan hal ini. Di Go, ini adalah error. Bab 08 sudah menampilkan versi import-nya:

package main

import "fmt"

func main() {
    // fmt.Println("hi")
}
# command-line-arguments
.\hello.go:3:8: "fmt" imported and not used

Variabel punya aturan yang sama. Kamu akan mengenal variabel dengan benar di Bab 11. Untuk sekarang, cukup ketahui bahwa name := "Keiko" di bawah ini membuat sebuah variabel, kotak bernama yang menyimpan teks Keiko:

package main

import "fmt"

func main() {
    name := "Keiko"
    fmt.Println("hi")
}
# command-line-arguments
.\hello.go:6:2: name declared and not used

Go berkata: kamu membuat name dan tidak pernah membacanya. Perbaikan: pakai, atau hapus barisnya. Aturan ini menangkap bug sungguhan, seperti membuat sebuah nilai lalu mencetak hal yang salah.

syntax error: unexpected semicolon or newline before {

Kamu menaruh kurung kurawal pembuka di barisnya sendiri.

package main

import "fmt"

func main()
{
    fmt.Println("hi")
}
# command-line-arguments
.\hello.go:6:1: syntax error: unexpected semicolon or newline before {

Yang satu ini terlihat aneh, karena kamu tidak pernah mengetik titik koma. Go menganggap akhir baris seperti func main() sebagai akhir sebuah pernyataan, seolah ada titik koma di sana, jadi { di baris berikutnya tidak lagi menjadi bagian darinya. Perbaikan: pindahkan { ke atas, ke akhir baris func main().

Siklus edit–jalankan–perbaiki

Cara yang benar untuk menangani error bukan dengan mencoba menemukannya semua dengan mata, tapi dengan menjalankan siklus yang ketat:

  1. Jalankan file.
  2. Baca error pertama: nomor baris, lalu kolom, lalu pesan.
  3. Perbaiki satu hal itu.
  4. Jalankan lagi.

Ulangi sampai berjalan bersih. Jangan perbaiki tiga hal sekaligus — satu "perbaikan" mungkin salah, dan kamu tidak bisa tahu perubahan mana yang membantu. Satu error, satu perbaikan, jalankan lagi.

Go bisa melaporkan beberapa error dalam satu kali jalan, dan itu tidak apa-apa. Perbaiki yang pertama lalu jalankan lagi, karena error itu mungkin menjadi penyebab yang lain. Error baru juga bisa muncul setelah perbaikan. Go hanya memeriksa nama setelah tanda baca di seluruh file benar, jadi error undefined: sering baru muncul setelah error syntax error: hilang. Itu kemajuan, bukan kemunduran.

Satu kesalahan terkadang menghasilkan pesan yang membingungkan, atau yang menunjuk ke baris setelah masalah sebenarnya. Kalau baris yang disebutkan terlihat baik-baik saja, cek tepat di atasnya. Error kurung kurawal di atas adalah contohnya: pesannya menyebut baris yang berisi {, sedangkan pemenggalan baris yang harus dihapus ada di akhir baris di atasnya.

Pesan-pesan di buku ini disalin dari Go 1.22. Go yang lebih baru mungkin memakai kata yang sedikit berbeda untuk sebagian pesan, tapi bentuk file:line:column: message tetap sama, dan cara membacanya juga sama.

Buka exercises/10/01-three-bugs.go. File ini tidak bisa dijalankan. Saat pertama dijalankan, file ini mencetak:

# command-line-arguments
exercises\10\01-three-bugs.go:10:1: syntax error: unexpected semicolon or newline before {
exercises\10\01-three-bugs.go:11:25: newline in string

Gunakan siklus edit–jalankan–perbaiki: baca error pertama, perbaiki hanya itu, jalankan lagi. Terus lakukan sampai mencetak All fixed!. Ada tiga bug, dan yang ketiga tidak muncul sampai dua yang pertama hilang.

Error bukan kegagalan

Setiap programmer membaca pesan error setiap hari. Itu bukan tanda kamu tidak pandai dalam hal ini — itu adalah proses bolak-balik yang normal dalam menulis kode. Membaca error dengan tenang hanya berarti kamu sudah membaca beberapa ribu di antaranya. Kamu sedang dalam perjalanan itu.

PR

File PR ada di exercises/10/homework/. Setiap starter di sini sengaja gagal sampai kamu memperbaikinya.

Soal 1 — Namai error-nya

Buka exercises/10/homework/01-name-the-error.go. File ini berisi satu baris yang rusak. Jalankan, baca pesannya, dan (dalam sebuah komentar di bagian bawah) tulis error mana dari empat error di bab ini yang sesuai. Kemudian perbaiki agar program menyapa Keiko.

Soal 2 — Perbaiki tanda kutipnya

Buka exercises/10/homework/02-fix-the-quote.go. File ini punya string yang tidak ditutup. Perbaiki agar program mencetak kutipan dalam satu baris.

Soal 3 — Perbaiki typo-nya

Buka exercises/10/homework/03-fix-the-typo.go. Nama fungsi salah eja, menghasilkan error undefined:. Perbaiki.

Tantangan — Tiga sekaligus

Buka exercises/10/homework/04-three-in-a-row.go. File ini punya tiga kesalahan terpisah, masing-masing satu: kurung kurawal pembuka di baris yang salah, string yang tidak ditutup, dan Println yang salah eja. Perbaiki satu per satu, jalankan setelah setiap perbaikan, sampai file mencetak:

Starting up
Working
done

Stuck atau sudah selesai? Buka halaman solusi PR.