Menu
CoddyTech

Membuka Bungkus Error dengan `errors.As`

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

Meskipun errors.Is membantumu mengidentifikasi nilai error tertentu dalam rantai, terkadang kamu perlu mengakses field dan data sebenarnya dari tipe error kustom. Fungsi errors.As menyediakan kemampuan ini dengan menemukan error pertama dalam rantai yang cocok dengan tipe tertentu dan mengambilnya untuk diperiksa.

Fungsi errors.As menerima dua parameter: error yang akan diperiksa dan pointer ke variabel dengan tipe error target. Jika menemukan tipe error yang cocok dalam rantai, fungsi ini menetapkan variabelmu ke error tersebut dan mengembalikan true:

var validationErr ValidationError
if errors.As(wrappedErr, &validationErr) {
    fmt.Printf("Field: %s, Message: %s\n", validationErr.Field, validationErr.Message)
}

Ini sangat berguna saat bekerja dengan tipe error khusus yang berisi konteks tambahan. Tidak seperti errors.Is yang hanya memeriksa kesetaraan, errors.As mengekstrak instance error yang sebenarnya, sehingga kamu dapat mengakses field dan method-nya. Ini membuat penanganan error menjadi lebih canggih dan informatif dalam aplikasi yang kompleks.

challenge icon

Tantangan

Mudah

Bangun sistem penanganan error API yang menggunakan errors.As untuk mengekstrak dan memeriksa tipe error kustom dari rangkaian error yang dibungkus. Tantangan ini menunjukkan cara menggunakan errors.As untuk mengakses field dan data dari tipe error kustom tertentu, bahkan ketika tipe tersebut telah dibungkus dengan konteks tambahan.

Kamu akan menerima dua input:

  • Sebuah string berisi detail permintaan API dengan format "endpoint,method,error_code,error_field" (misalnya, "/users,POST,400,email")
  • Sebuah string berisi konteks sistem dengan format "service_name,request_id" (misalnya, "UserAPI,req_12345")

Tugasmu adalah:

  1. Buat tipe error kustom bernama struct APIError dengan tiga field:
    • Code (int) untuk kode status HTTP
    • Field (string) untuk field yang menyebabkan error
    • Message (string) untuk deskripsi error
  2. Implementasikan method Error() string untuk APIError yang mengembalikan: "API error [code]: [message] (field: [field])"
  3. Urai input pertama dengan memisahkannya berdasarkan koma untuk mendapatkan endpoint, method, kode error, dan field error
  4. Urai input kedua dengan memisahkannya berdasarkan koma untuk mendapatkan nama service dan ID permintaan
  5. Ubah string kode error menjadi bilangan bulat
  6. Buat instance APIError berdasarkan kode error:
    • Jika kodenya 400: message "invalid request data"
    • Jika kodenya 401: message "authentication required"
    • Jika kodenya 404: message "resource not found"
    • Jika kodenya 500: message "internal server error"
    • Untuk kode lainnya: message "unknown error"
  7. Buat error terbungkus tingkat endpoint menggunakan fmt.Errorf dengan %w: "[method] [endpoint] failed: %w"
  8. Buat error terbungkus tingkat service: "[service_name] request [request_id] failed: %w"
  9. Gunakan errors.As untuk mengekstrak APIError dari rangkaian error terbungkus dan tampilkan hasil ekstraksinya:
    • Jika ekstraksi berhasil: "API error extracted successfully"
    • Jika ekstraksi gagal: "Failed to extract API error"
  10. Jika ekstraksi berhasil, tampilkan detail error yang diekstrak:
    • "Extracted Error Details:"
    • "Code: [code]"
    • "Field: [field]"
    • "Message: [message]"
    • "Full error: [full_error_message_from_Error_method]"
  11. Tampilkan rangkaian error lengkap:
    • "Error Chain:"
    • "Original: [original_api_error_message]"
    • "Endpoint level: [endpoint_level_error_message]"
    • "Service level: [service_level_error_message]"
  12. Tampilkan analisis akhir:
    • "Error Analysis:"
    • "Service: [service_name]"
    • "Request ID: [request_id]"
    • "Endpoint: [method] [endpoint]"
    • "HTTP Status: [code]"
    • "Problem Field: [field]"
    • "Error Category: [error_category]", dengan error_category berupa "Client Error" untuk kode 400-499, "Server Error" untuk kode 500-599, atau "Unknown" untuk kode lainnya

Gunakan package strings untuk memisahkan string input berdasarkan koma, package strconv untuk mengubah string kode error menjadi bilangan bulat, package errors untuk errors.As, dan package fmt untuk membungkus error. Tantangan ini menunjukkan cara errors.As memungkinkan kamu mengakses field dan method tertentu dari tipe error kustom di dalam rangkaian error terbungkus, sehingga kamu dapat melakukan penanganan dan analisis error yang canggih.

Coba sendiri

package main

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

func main() {
	// Baca input
	var apiDetails string
	var systemContext string
	fmt.Scanln(&apiDetails)
	fmt.Scanln(&systemContext)
	
	// Uraikan input
	apiParts := strings.Split(apiDetails, ",")
	endpoint := apiParts[0]
	method := apiParts[1]
	errorCodeStr := apiParts[2]
	errorField := apiParts[3]
	
	contextParts := strings.Split(systemContext, ",")
	serviceName := contextParts[0]
	requestID := contextParts[1]
	
	// Ubah kode error menjadi bilangan bulat
	errorCode, _ := strconv.Atoi(errorCodeStr)
	
	// TODO: Tulis kodemu di bawah ini
	// 1. Buat struct APIError dengan field Code, Field, dan Message
	// 2. Implementasikan method Error() untuk APIError
	// 3. Buat instans APIError berdasarkan kode error
	// 4. Buat error yang dibungkus pada tingkat endpoint dan tingkat layanan
	// 5. Gunakan errors.As untuk mengekstrak APIError dari rantai error yang dibungkus
	// 6. Tampilkan hasil ekstraksi dan detail error
	// 7. Tampilkan rantai error dan analisis akhir
	
}
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