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.
Tantangan
MudahBangun 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:
- Buat tipe error kustom bernama struct
APIErrordengan tiga field:Code(int) untuk kode status HTTPField(string) untuk field yang menyebabkan errorMessage(string) untuk deskripsi error
- Implementasikan method
Error() stringuntukAPIErroryang mengembalikan:"API error [code]: [message] (field: [field])" - Urai input pertama dengan memisahkannya berdasarkan koma untuk mendapatkan endpoint, method, kode error, dan field error
- Urai input kedua dengan memisahkannya berdasarkan koma untuk mendapatkan nama service dan ID permintaan
- Ubah string kode error menjadi bilangan bulat
- Buat instance
APIErrorberdasarkan 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"
- Jika kodenya 400: message
- Buat error terbungkus tingkat endpoint menggunakan
fmt.Errorfdengan%w:"[method] [endpoint] failed: %w" - Buat error terbungkus tingkat service:
"[service_name] request [request_id] failed: %w" - Gunakan
errors.Asuntuk mengekstrakAPIErrordari rangkaian error terbungkus dan tampilkan hasil ekstraksinya:- Jika ekstraksi berhasil:
"API error extracted successfully" - Jika ekstraksi gagal:
"Failed to extract API error"
- Jika ekstraksi berhasil:
- 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]"
- Tampilkan rangkaian error lengkap:
"Error Chain:""Original: [original_api_error_message]""Endpoint level: [endpoint_level_error_message]""Service level: [service_level_error_message]"
- 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
}Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Logika & Alur
1Alur Kontrol Lanjutan
switch dengan `fallthrough`Keluar dari Perulangan BersarangMelanjutkan Perulangan TertentuPernyataan `goto`Rangkuman, Kontrol Perulangan Lanjutan4Proyek: Daftar Tugas Sederhana
Menyiapkan ProyekMenambahkan Tugas7Penanganan Error secara Mendalam
Tipe Error KustomMembungkus Error dengan `%w`Membuka Bungkus Error dengan `errors.Is`Membuka Bungkus Error dengan `errors.As`Memahami `panic`Menggunakan `recover`Rangkuman: Pembagian Aman2Struct dan Method
Mendefinisikan Method pada StructPenerima NilaiPenerima PointerMemilih PenerimaMethod vs FungsiRekap: Perilaku Struct5Map secara Mendalam
Map Berisi StructPointer sebagai Nilai MapMenguji Map NilMembandingkan MapRingkasan: Penghitung Frekuensi Kata8Proyek: Inventaris Sederhana
Gambaran Umum ProyekMemeriksa Stok3Interface (Dasar)
Apa Itu Interface?Mendefinisikan InterfaceMengimplementasikan InterfaceMenggunakan Tipe InterfaceInterface KosongType AssertionType SwitchRingkasan: Bentuk dan PerilakuLatihan sendiri: Compiler Go online