Menggunakan `recover`
Termasuk bagian Logika & Alur dalam perjalanan GO di Coddy. Pelajaran 43 dari 68.
Meskipun panic langsung menghentikan programmu, Go menyediakan cara untuk mendapatkan kembali kendali melalui fungsi recover. Fungsi recover memungkinkan kamu menangkap panic dan menanganinya dengan baik, sehingga seluruh programmu tidak mengalami crash.
Namun, recover memiliki persyaratan yang sangat spesifik: fungsi ini hanya dapat digunakan di dalam fungsi yang ditunda. Saat panic terjadi, Go menjalankan semua fungsi yang ditunda sebelum program berakhir, sehingga recover berkesempatan untuk menangani panic tersebut:
func riskyFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("something went wrong!")
}Fungsi recover mengembalikan nilai yang diteruskan ke panic, atau nil jika tidak terjadi panic. Dengan begitu, kamu bisa memeriksa apakah panic terjadi dan mengambil tindakan yang sesuai, seperti mencatat error atau melakukan operasi pembersihan.
Seperti panic, recover sebaiknya digunakan secukupnya di Go. Penggunaan ini paling sering terlihat dalam situasi seperti server web, saat kamu ingin mencegah panic pada satu permintaan menyebabkan seluruh server berhenti, sehingga server dapat terus melayani permintaan lainnya.
Tantangan
MudahBuat handler permintaan server web yang menggunakan recover untuk menangani panic dengan baik dan mencegah seluruh server berhenti. Tantangan ini menunjukkan cara menggunakan recover di dalam fungsi tertunda untuk menangkap panic dan menjaga kestabilan server.
Kamu akan menerima dua input:
- Sebuah string berisi detail permintaan dengan format
"endpoint,method,action"(misalnya,"/api/users,GET,process") - Sebuah string berisi konfigurasi server dengan format
"server_name,max_requests"(misalnya,"WebServer,100")
Tugasmu adalah:
- Parse input pertama dengan memisahkannya berdasarkan koma untuk mendapatkan endpoint, method, dan action
- Parse input kedua dengan memisahkannya berdasarkan koma untuk mendapatkan nama server dan jumlah permintaan maksimum
- Ubah string jumlah permintaan maksimum menjadi bilangan bulat
- Buat fungsi bernama
handleRequestyang menerima endpoint, method, action, dan nama server sebagai parameter - Di dalam
handleRequest, tambahkan fungsi tertunda yang menggunakanrecoveruntuk menangkap panic apa pun:- Jika panic berhasil dipulihkan (
recovermengembalikan nilai non-nil), cetak:"Server [server_name] recovered from panic: [panic_value]" - Setelah menangani panic, cetak:
"Request handling completed safely"
- Jika panic berhasil dipulihkan (
- Setelah fungsi tertunda, simulasikan pemrosesan permintaan berdasarkan action:
- Jika action adalah
"process": cetak"Processing [method] request to [endpoint]" - Jika action adalah
"panic_nil": cetak"Attempting dangerous operation"lalu panggilpanic("nil pointer access") - Jika action adalah
"panic_overflow": cetak"Attempting resource allocation"lalu panggilpanic("memory overflow") - Jika action adalah
"panic_timeout": cetak"Attempting database connection"lalu panggilpanic("connection timeout") - Untuk action lainnya: cetak
"Unknown action: [action]"lalu panggilpanic("invalid action")
- Jika action adalah
- Di fungsi utama, cetak pesan saat server dimulai:
"Starting [server_name] with max [max_requests] requests" - Panggil fungsi
handleRequestdengan parameter yang sudah di-parse - Setelah pemanggilan fungsi, cetak status server:
"Server [server_name] is still running" - Terakhir, cetak ringkasan:
"Server Summary:""Name: [server_name]""Max Requests: [max_requests]""Last Request: [method] [endpoint]""Action Performed: [action]""Status: Operational"
Gunakan package strings untuk memisahkan string input berdasarkan koma dan package strconv untuk mengubah string jumlah permintaan maksimum menjadi bilangan bulat. Tantangan ini menunjukkan cara recover memungkinkan server menangani panic tak terduga dengan baik, sehingga kegagalan permintaan individual tidak membuat seluruh sistem berhenti.
Coba sendiri
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// Baca input
var requestDetails string
var serverConfig string
fmt.Scanln(&requestDetails)
fmt.Scanln(&serverConfig)
// Uraikan detail permintaan
requestParts := strings.Split(requestDetails, ",")
endpoint := requestParts[0]
method := requestParts[1]
action := requestParts[2]
// Uraikan konfigurasi server
configParts := strings.Split(serverConfig, ",")
serverName := configParts[0]
maxRequests, _ := strconv.Atoi(configParts[1])
// TODO: Tulis kodemu di bawah ini
// Buat fungsi handleRequest dengan mekanisme recover
// Cetak pesan saat server mulai berjalan
// Panggil fungsi handleRequest
// Cetak status dan ringkasan server
}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