Menu
CoddyTech

Membuka Bungkus Error dengan `errors.Is`

Termasuk bagian Logika & Alur dalam perjalanan GO di Coddy. Pelajaran 40 dari 68.

Saat menangani error yang dibungkus, kamu perlu cara untuk memeriksa apakah error tertentu ada di bagian mana pun dalam rantai error. Fungsi errors.Is menyediakan kemampuan ini, sehingga kamu dapat mengidentifikasi error sentinel meskipun sudah dibungkus beberapa kali.

Fungsi errors.Is menerima dua parameter: error yang ingin kamu periksa dan error target yang kamu cari. Fungsi ini mengembalikan true jika error target ditemukan di mana saja dalam rantai error:

var ErrNotFound = errors.New("not found")

wrappedErr := fmt.Errorf("failed to load user: %w", ErrNotFound)

if errors.Is(wrappedErr, ErrNotFound) {
    fmt.Println("This is a not found error")
}

Ini adalah cara modern yang direkomendasikan untuk memeriksa error tertentu di Go. Tidak seperti perbandingan string atau pemeriksaan kesetaraan langsung, errors.Is bekerja dengan benar pada error yang dibungkus dan menelusuri rantai error untuk menemukan kecocokan. Hal ini membuat penanganan error-mu tangguh dan andal, bahkan saat error melewati beberapa lapisan aplikasimu.

challenge icon

Tantangan

Mudah

Bangun sistem pemantauan koneksi database yang menggunakan errors.Is untuk mengidentifikasi error koneksi tertentu dalam rantai error yang dibungkus. Tantangan ini menunjukkan cara menggunakan errors.Is untuk mendeteksi error sentinel meskipun error tersebut telah dibungkus dengan konteks tambahan melalui beberapa lapisan aplikasi.

Kamu akan menerima dua input:

  • String yang berisi detail operasi database dalam format "database_name,operation,error_type" (misalnya, "users_db,connect,connection_timeout")
  • String yang berisi konteks aplikasi dalam format "service_name,retry_count" (misalnya, "AuthService,3")

Tugasmu adalah:

  1. Definisikan tiga error sentinel menggunakan errors.New():
    • ErrConnectionTimeout dengan pesan "connection timeout"
    • ErrConnectionRefused dengan pesan "connection refused"
    • ErrDatabaseNotFound dengan pesan "database not found"
  2. Parse input pertama dengan memisahkannya berdasarkan koma untuk mendapatkan nama database, operasi, dan tipe error
  3. Parse input kedua dengan memisahkannya berdasarkan koma untuk mendapatkan nama layanan dan jumlah percobaan ulang
  4. Buat error asli berdasarkan tipe error:
    • Jika tipe error adalah "connection_timeout": gunakan ErrConnectionTimeout
    • Jika tipe error adalah "connection_refused": gunakan ErrConnectionRefused
    • Jika tipe error adalah "database_not_found": gunakan ErrDatabaseNotFound
    • Untuk tipe error lainnya: gunakan errors.New("unknown database error")
  5. Buat error terbungkus tingkat database menggunakan fmt.Errorf dengan %w: "failed to [operation] database [database_name]: %w"
  6. Buat error terbungkus tingkat layanan: "[service_name] database operation failed after [retry_count] retries: %w"
  7. Gunakan errors.Is untuk memeriksa apakah error terbungkus terakhir cocok dengan setiap error sentinel, lalu tampilkan hasilnya:
    • "Checking for connection timeout: [true/false]"
    • "Checking for connection refused: [true/false]"
    • "Checking for database not found: [true/false]"
  8. Tampilkan rantai error:
    • "Error Chain:"
    • "Original: [original_error_message]"
    • "Database level: [database_level_error_message]"
    • "Service level: [service_level_error_message]"
  9. Tampilkan analisis error:
    • "Error Analysis:"
    • "Database: [database_name]"
    • "Operation: [operation]"
    • "Service: [service_name]"
    • "Retries: [retry_count]"
    • "Error type detected: [detected_error_type]" dengan detected_error_type berupa salah satu dari "Connection Timeout", "Connection Refused", "Database Not Found", atau "Unknown Error"

Gunakan package strings untuk memisahkan string input berdasarkan koma, package errors untuk error sentinel dan errors.Is, serta package fmt untuk membungkus error. Tantangan ini menunjukkan bahwa errors.Is menyediakan identifikasi error yang andal dan berfungsi dengan benar pada error yang dibungkus, sehingga penting untuk penanganan error yang dapat diandalkan dalam aplikasi kompleks.

Coba sendiri

package main

import (
	"errors"
	"fmt"
	"strings"
)

func main() {
	// Baca input
	var dbOperation string
	var appContext string
	fmt.Scanln(&dbOperation)
	fmt.Scanln(&appContext)
	
	// Uraikan input
	dbParts := strings.Split(dbOperation, ",")
	databaseName := dbParts[0]
	operation := dbParts[1]
	errorType := dbParts[2]
	
	contextParts := strings.Split(appContext, ",")
	serviceName := contextParts[0]
	retryCount := contextParts[1]
	
	// TODO: Tulis kodemu di bawah ini
	// 1. Definisikan tiga sentinel error menggunakan errors.New()
	// 2. Buat error asli berdasarkan jenis error
	// 3. Buat error terbungkus pada tingkat database menggunakan fmt.Errorf dengan %w
	// 4. Buat error terbungkus pada tingkat layanan
	// 5. Gunakan errors.Is untuk memeriksa setiap sentinel error
	// 6. Tampilkan hasil dan rantai error
	
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Logika & Alur

Latihan sendiri: Compiler Go online