Menu
Coddy logo textTech

Używanie `recover`

Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 43 z 68.

Chociaż panic natychmiast zatrzymuje program, Go umożliwia odzyskanie kontroli za pomocą funkcji recover. Funkcja recover pozwala przechwycić panikę i obsłużyć ją w kontrolowany sposób, zapobiegając awarii całego programu.

Jednak recover ma bardzo konkretne wymaganie: można go używać tylko wewnątrz odroczonej funkcji. Gdy wystąpi panika, Go wykonuje wszystkie odroczone funkcje przed zakończeniem programu, dając recover szansę na przechwycenie paniki:

func riskyFunction() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    
    panic("something went wrong!")
}

Funkcja recover zwraca wartość przekazaną do panic lub nil, jeśli nie wystąpiła panika. Dzięki temu możesz sprawdzić, czy wystąpiła panika, i podjąć odpowiednie działania, takie jak zapisanie błędu w dzienniku lub wykonanie operacji porządkowych.

Podobnie jak panic, recover należy stosować oszczędnie w Go. Najczęściej używa się go w sytuacjach takich jak działanie serwerów WWW, gdy chcesz zapobiec temu, by panika podczas obsługi pojedynczego żądania spowodowała awarię całego serwera, dzięki czemu może on nadal obsługiwać inne żądania.

challenge icon

Wyzwanie

Łatwy

Zbuduj procedurę obsługi żądań serwera WWW, która używa recover, aby łagodnie obsługiwać paniki i zapobiegać awarii całego serwera. To wyzwanie pokazuje, jak używać recover wewnątrz odroczonej funkcji, aby przechwytywać paniki i utrzymywać stabilność serwera.

Otrzymasz dwa wejścia:

  • Ciąg zawierający szczegóły żądania w formacie "endpoint,method,action" (np. "/api/users,GET,process")
  • Ciąg zawierający konfigurację serwera w formacie "server_name,max_requests" (np. "WebServer,100")

Twoim zadaniem jest:

  1. Przeanalizować pierwsze wejście, dzieląc je po przecinkach, aby uzyskać endpoint, method i action
  2. Przeanalizować drugie wejście, dzieląc je po przecinkach, aby uzyskać nazwę serwera i maksymalną liczbę żądań
  3. Przekonwertować ciąg z maksymalną liczbą żądań na liczbę całkowitą
  4. Utworzyć funkcję o nazwie handleRequest, która przyjmuje endpoint, method, action i nazwę serwera jako parametry
  5. Wewnątrz handleRequest dodać odroczoną funkcję, która używa recover, aby przechwycić wszelkie paniki:
    • Jeśli panika zostanie przechwycona (recover zwraca wartość różną od nil), wyświetlić: "Server [server_name] recovered from panic: [panic_value]"
    • Po obsłużeniu paniki wyświetlić: "Request handling completed safely"
  6. Po odroczonej funkcji zasymulować przetwarzanie żądania w zależności od działania:
    • Jeśli action to "process": wyświetlić "Processing [method] request to [endpoint]"
    • Jeśli action to "panic_nil": wyświetlić "Attempting dangerous operation", a następnie wywołać panic("nil pointer access")
    • Jeśli action to "panic_overflow": wyświetlić "Attempting resource allocation", a następnie wywołać panic("memory overflow")
    • Jeśli action to "panic_timeout": wyświetlić "Attempting database connection", a następnie wywołać panic("connection timeout")
    • Dla każdej innej wartości action: wyświetlić "Unknown action: [action]", a następnie wywołać panic("invalid action")
  7. W funkcji main wyświetlić komunikat o uruchomieniu serwera: "Starting [server_name] with max [max_requests] requests"
  8. Wywołać funkcję handleRequest z przeanalizowanymi parametrami
  9. Po wywołaniu funkcji wyświetlić status serwera: "Server [server_name] is still running"
  10. Na koniec wyświetlić podsumowanie:
    • "Server Summary:"
    • "Name: [server_name]"
    • "Max Requests: [max_requests]"
    • "Last Request: [method] [endpoint]"
    • "Action Performed: [action]"
    • "Status: Operational"

Użyj pakietu strings, aby dzielić ciągi wejściowe po przecinkach, oraz pakietu strconv, aby przekonwertować ciąg z maksymalną liczbą żądań na liczbę całkowitą. To wyzwanie pokazuje, jak recover pozwala serwerom łagodnie obsługiwać nieoczekiwane paniki, zapobiegając temu, by awarie pojedynczych żądań unieruchamiały cały system.

Spróbuj swoich sił

package main

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

func main() {
	// Odczytaj dane wejściowe
	var requestDetails string
	var serverConfig string
	fmt.Scanln(&requestDetails)
	fmt.Scanln(&serverConfig)
	
	// Przeanalizuj szczegóły żądania
	requestParts := strings.Split(requestDetails, ",")
	endpoint := requestParts[0]
	method := requestParts[1]
	action := requestParts[2]
	
	// Przeanalizuj konfigurację serwera
	configParts := strings.Split(serverConfig, ",")
	serverName := configParts[0]
	maxRequests, _ := strconv.Atoi(configParts[1])
	
	// TODO: Napisz swój kod poniżej
	// Utwórz funkcję handleRequest z mechanizmem recover
	// Wyświetl komunikat o uruchomieniu serwera
	// Wywołaj funkcję handleRequest
	// Wyświetl stan serwera i podsumowanie
	
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Logika i przepływ sterowania

Poćwicz samodzielnie: Kompilator Go online