Menu
Coddy logo textTech

Opakowywanie błędów za pomocą `%w`

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

Gdy w aplikacji wystąpią błędy, często potrzebują dodatkowego kontekstu, gdy przemieszczają się w górę przez różne warstwy kodu. Go zapewnia skuteczny mechanizm, który to umożliwia: opakowywanie błędów za pomocą czasownika formatującego %w w funkcji fmt.Errorf.

Opakowywanie błędów pozwala dodać kontekstowe informacje do istniejącego błędu, zachowując pierwotny błąd. Tworzy to łańcuch błędów, który przechowuje pełną historię tego, co poszło nie tak:

originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)

Specyfikator %w jest wyjątkowy — informuje fmt.Errorf, aby opakować błąd, zamiast po prostu przekształcać go w ciąg znaków. Dzięki temu oryginalny błąd zostaje zachowany i można go później sprawdzić za pomocą funkcji takich jak errors.Is i errors.As.

Ten wzorzec jest szczególnie przydatny w większych aplikacjach, w których błąd może przechodzić przez wiele funkcji, a każda z nich dodaje własny kontekst. Na przykład błąd połączenia z bazą danych może zostać opakowany komunikatem „nie udało się połączyć z bazą danych”, a następnie opakowany ponownie komunikatem „nie można uruchomić serwera”, tworząc przejrzysty zapis tego, co się stało i gdzie.

challenge icon

Wyzwanie

Łatwy

Zbuduj system przetwarzania plików, który opakowuje błędy w informacje kontekstowe w miarę ich propagowania przez różne warstwy aplikacji. To wyzwanie pokazuje, jak używać specyfikatora formatu %w z funkcją fmt.Errorf, aby tworzyć łańcuchy błędów zachowujące pierwotny błąd i dodające istotny kontekst.

Otrzymasz dwa dane wejściowe:

  • Ciąg znaków zawierający szczegóły operacji na pliku w formacie "filename,operation,status" (np. "config.json,read,permission_denied")
  • Ciąg znaków zawierający kontekst systemowy w formacie "service_name,component" (np. "UserService,ConfigLoader")

Twoje zadanie:

  1. Przeanalizuj pierwsze dane wejściowe, dzieląc je po przecinkach, aby uzyskać nazwę pliku, operację i status
  2. Przeanalizuj drugie dane wejściowe, dzieląc je po przecinkach, aby uzyskać nazwę usługi i komponent
  3. Utwórz pierwotny błąd na podstawie statusu, używając errors.New():
    • Jeśli status to "permission_denied": "permission denied"
    • Jeśli status to "not_found": "file not found"
    • Jeśli status to "corrupted": "file corrupted"
    • Dla każdego innego statusu: "unknown error"
  4. Utwórz opakowany błąd na poziomie pliku, używając fmt.Errorf z %w: "failed to [operation] file [filename]: %w"
  5. Utwórz opakowany błąd na poziomie komponentu: "[component] error: %w"
  6. Utwórz opakowany błąd na poziomie usługi: "[service_name] operation failed: %w"
  7. Wyświetl łańcuch błędów, wypisując każdy poziom:
    • "Original error: [original_error_message]"
    • "File level: [file_level_error_message]"
    • "Component level: [component_level_error_message]"
    • "Service level: [service_level_error_message]"
  8. Wyświetl podsumowanie łańcucha błędów:
    • "Error Chain Summary:"
    • "File: [filename]"
    • "Operation: [operation]"
    • "Component: [component]"
    • "Service: [service_name]"
    • "Root cause: [original_error_message]"

Użyj pakietu strings, aby podzielić ciągi wejściowe po przecinkach, pakietu errors, aby utworzyć pierwotny błąd, oraz pakietu fmt, aby utworzyć opakowane błędy. To wyzwanie pokazuje, jak opakowywanie błędów za pomocą %w tworzy przejrzystą ścieżkę kontekstu, gdy błędy przechodzą przez różne warstwy aplikacji, znacznie ułatwiając debugowanie.

Spróbuj swoich sił

package main

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

func main() {
	// Wczytaj dane wejściowe
	var fileDetails string
	var systemContext string
	fmt.Scanln(&fileDetails)
	fmt.Scanln(&systemContext)
	
	// Przeanalizuj dane wejściowe
	fileInfo := strings.Split(fileDetails, ",")
	filename := fileInfo[0]
	operation := fileInfo[1]
	status := fileInfo[2]
	
	contextInfo := strings.Split(systemContext, ",")
	serviceName := contextInfo[0]
	component := contextInfo[1]
	
	// TODO: Napisz swój kod poniżej
	// Utwórz pierwotny błąd na podstawie statusu
	// Utwórz błąd opakowany na poziomie pliku
	// Utwórz błąd opakowany na poziomie komponentu
	// Utwórz błąd opakowany na poziomie usługi
	// Wyświetl każdy poziom błędu oraz 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