Error Handling — Go

Error Handling di Go Go tidak menggunakan try/catch seperti bahasa lain. Sebagai gantinya, error adalah nilai yang dikembalikan dari fungsi dan harus…

Di Go, kegagalan bukan sesuatu yang "dilempar" lalu ditangkap try/catch. Kegagalan adalah nilai biasa bertipe error, yang dikembalikan fungsi sebagai hasil terakhirnya. Bayangin kasir Warung Bakso Mas Bimo menerima uang yang kurang. Kasir gak membanting meja; ia menyerahkan kembalian Rp0 bersama secarik catatan: "uang kurang". Yang menerima wajib membaca catatan itu dulu sebelum percaya pada kembaliannya.

🧪 Tebakan cepat: kembalian, _ := bayar(32000, "20000") lalu fmt.Println("kembalian:", kembalian). Uangnya kurang. Program berhenti dengan error, atau tenang-tenang mencetak kembalian: 0? Tebak dulu, jawabannya ada di bagian "Jangan buang error dengan _".

error itu interface

error adalah interface bawaan Go dengan satu method:

type error interface {
	Error() string
}

Tipe apa pun yang punya Error() string adalah sebuah error. Nilai nil artinya gak ada error. Cara paling gampang membuatnya: errors.New("uang kurang") dari package errors.

Pola if err != nil

package main

import (
	"errors"
	"fmt"
	"strconv"
)

var ErrUangKurang = errors.New("uang kurang")

func bayar(total int, input string) (int, error) {
	uang, err := strconv.Atoi(input)
	if err != nil {
		return 0, fmt.Errorf("baca uang %q: %w", input, err)
	}
	if uang < total {
		return 0, fmt.Errorf("bayar %d dari %d: %w", uang, total, ErrUangKurang)
	}
	return uang - total, nil
}

func main() {
	kembalian, err := bayar(32000, "50000")
	if err != nil {
		fmt.Println("gagal:", err)
		return
	}
	fmt.Println("kembalian:", kembalian)
}
input err Tercetak
"50000" nil kembalian: 18000
"32000" nil kembalian: 0
"20000" uang kurang gagal: bayar 20000 dari 32000: uang kurang
"50rb" bukan angka gagal: baca uang "50rb": strconv.Atoi: parsing "50rb": invalid syntax

Contoh kecil yang sama: _, err := strconv.Atoi("abc") gagal karena "abc" bukan angka, jadi if err != nil { fmt.Println("error") } mencetak error.

Di latihan: safeDivide

Fungsi safeDivide(a, b float64) (float64, error) sudah ada di kode awal: kalau b == 0 ia mengembalikan errors.New("tidak bisa membagi dengan nol"), selain itu a / b, nil. Tugasmu ada di main: terima dua hasilnya, lalu cek dengan if err != nil.

3.3333333333333335
Error: tidak bisa membagi dengan nol

safeDivide(10, 3) memberi 3.3333333333333335 (begitulah float64 mencetak 10/3), dan safeDivide(10, 0) memberi error yang pesannya dicetak.

errors.New atau fmt.Errorf

errors.Is(err, ErrUangKurang) menelusuri bungkusan itu dan menjawab apakah ErrUangKurang ada di dalamnya:

fmt.Println(errors.Is(err, ErrUangKurang)) // true dengan %w, false dengan %v

Dengan %v, pesannya persis sama, tapi yang disalin cuma teksnya. Error aslinya hilang, jadi errors.Is menjawab false.

📌 errors.As: ambil detail dari error

errors.As mencari error dengan tipe tertentu di dalam bungkusan, lalu mengisinya ke variabel:

var numErr *strconv.NumError
if errors.As(err, &numErr) {
	fmt.Println(numErr.Func, numErr.Num) // Atoi 50rb
}

Untuk input "50rb", error dari strconv.Atoi bertipe *strconv.NumError, jadi numErr.Num berisi teks yang gagal dibaca. Membuat tipe error sendiri ada di lesson berikutnya, Custom Errors.

Jangan buang error dengan _

kembalian, _ := bayar(32000, "20000")
fmt.Println("kembalian:", kembalian)
kembalian: 0

Gak ada error yang muncul. Itu jawaban tebakannya: program tenang-tenang mencetak kembalian: 0, padahal pembeli belum lunas. Error di Go gak menghentikan apa pun sendiri; kalau dibuang, peringatannya hilang begitu saja.

⚠️ Jebakan yang sering ketemu

TL;DR: Error di Go adalah nilai bertipe error, interface dengan method Error() string, dikembalikan sebagai hasil terakhir; nil artinya gak ada error. Polanya: hasil, err := f(), lalu if err != nil { ... return } sebelum hasilnya dipakai. errors.New membuat error dengan pesan tetap, fmt.Errorf menambah keterangan, dan %w membungkus error aslinya supaya errors.Is(err, ErrUangKurang) dan errors.As(err, &numErr) masih menemukannya; %v cuma menyalin teks. strconv.Atoi("abc") mengembalikan error. Di latihan, safeDivide(10, 3) mencetak 3.3333333333333335 dan safeDivide(10, 0) mencetak tidak bisa membagi dengan nol. Jangan buang error dengan _.

Yang akan kamu pelajari