🖥️ VS Code: Problems Panel untuk Error Real-time
Dengan extension Go, VS Code menampilkan semua error Go di panel Problems (tekan Ctrl+Shift+M) secara real-time saat kamu mengetik. Hover di atas garis merah di editor untuk melihat detail error. Klik Quick Fix (💡) untuk saran perbaikan otomatis.
Ini salah satu hal yang paling membedakan Go dari bahasa lain. Tidak ada try/catch/finally. Error adalah nilai biasa yang dikembalikan oleh fungsi — kamu wajib menanganinya secara eksplisit.
Kenapa Go Tidak Pakai try/catch?
Di banyak bahasa, exception bisa "terbang" melewati banyak layer tanpa terdeteksi sampai crash. Go memaksa developer menangani error di tempat yang tepat — hasilnya kode lebih eksplisit dan lebih mudah di-debug.
error Interface
error di Go adalah interface sederhana:
type error interface {
Error() string
}
Setiap tipe yang punya method Error() string otomatis implementasi interface error.
Pola Dasar
import (
"errors"
"fmt"
)
func bagi(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("pembagi tidak boleh nol")
}
return a / b, nil
}
func main() {
hasil, err := bagi(10, 0)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Hasil:", hasil)
}
Pola if err != nil ini akan kamu temukan di setiap kode Go. Ini memang disengaja — Go percaya explicit is better than implicit.
fmt.Errorf — Buat Error dengan Konteks
func ambilUser(id int) (*User, error) {
user, err := db.FindByID(id)
if err != nil {
// Wrap error dengan konteks tambahan (Go 1.13+)
return nil, fmt.Errorf("ambilUser(%d): %w", id, err)
}
return user, nil
}
// Output error-nya jadi:
// "ambilUser(42): record not found"
%w (wrap) berbeda dengan %v — error yang di-wrap bisa di-unwrap dengan errors.Is dan errors.As.
Custom Error Type
// Definisi custom error
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validasi gagal pada field '%s': %s", e.Field, e.Message)
}
// Penggunaan
func validasiEmail(email string) error {
if email == "" {
return &ValidationError{Field: "email", Message: "tidak boleh kosong"}
}
if len(email) < 5 {
return &ValidationError{Field: "email", Message: "terlalu pendek"}
}
return nil
}
errors.Is — Cek Jenis Error
var ErrNotFound = errors.New("tidak ditemukan")
var ErrUnauthorized = errors.New("tidak terautentikasi")
func ambilData(id int) error {
return fmt.Errorf("ambilData: %w", ErrNotFound) // wrap
}
err := ambilData(99)
if errors.Is(err, ErrNotFound) {
fmt.Println("Data tidak ada, tampilkan 404")
} else if errors.Is(err, ErrUnauthorized) {
fmt.Println("Perlu login dulu")
}
errors.As — Ekstrak Detail Error
err := validasiEmail("")
var valErr *ValidationError
if errors.As(err, &valErr) {
fmt.Printf("Field: %s\n", valErr.Field)
fmt.Printf("Pesan: %s\n", valErr.Message)
}
Panic & Recover
Panic adalah cara Go untuk menangani kesalahan yang benar-benar tidak terduga (seperti index out of range, nil pointer). Gunakan dengan hati-hati — ini bukan pengganti error handling biasa.
func paksa(nilai int) {
if nilai < 0 {
panic("nilai tidak boleh negatif!") // program crash jika tidak di-recover
}
}
// Recover harus ada di dalam defer
func safe() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Panic ditangkap:", r)
}
}()
paksa(-1) // akan panic, tapi di-recover
fmt.Println("Ini tidak akan tercetak")
}
func main() {
safe()
fmt.Println("Program tetap jalan")
}
Best Practice: Wrap Error, Jangan Ditelan
// ❌ Buruk — error ditelan, tidak ada informasi
if err != nil {
return nil, errors.New("error")
}
// ❌ Buruk — error di-log tapi tetap di-return, nanti di-log lagi
if err != nil {
log.Println(err)
return nil, err
}
// ✅ Baik — wrap dengan konteks yang jelas
if err != nil {
return nil, fmt.Errorf("createOrder(userID=%d): %w", userID, err)
}
errors.New("...") | Error sederhana tanpa konteks dinamis |
fmt.Errorf("...: %w", err) | Tambah konteks + wrap error asli |
| Custom error struct | Error dengan data tambahan (field, code, dll) |
errors.Is | Cek jenis error (termasuk yang di-wrap) |
panic/recover | Hanya untuk kondisi yang benar-benar tidak terduga |
Komentar 0