Fehler-Wrapping mit `%w`
Teil des Abschnitts Logik & Ablauf der GO-Journey von Coddy — Lektion 39 von 68.
Wenn Fehler in Ihrer Anwendung auftreten, benötigen sie oft zusätzlichen Kontext, während sie durch verschiedene Ebenen Ihres Codes nach oben gereicht werden. Go bietet hierfür einen leistungsstarken Mechanismus durch Error-Wrapping unter Verwendung des Format-Verbs %w mit fmt.Errorf.
Error Wrapping ermöglicht es Ihnen, kontextbezogene Informationen zu einem bestehenden Fehler hinzuzufügen, während der ursprüngliche Fehler darunter erhalten bleibt. Dies erzeugt eine Fehlerkette, die den vollständigen Verlauf dessen beibehält, was schiefgelaufen ist:
originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)Das Verb %w ist speziell – es weist fmt.Errorf an, den Fehler zu verpacken (wrap), anstatt ihn nur in einen String umzuwandeln. Dies bewahrt den ursprünglichen Fehler, sodass er später mit Funktionen wie errors.Is und errors.As untersucht werden kann.
Dieses Muster ist besonders wertvoll in größeren Anwendungen, in denen ein Fehler mehrere Funktionen durchlaufen kann, wobei jede ihren eigenen Kontext hinzufügt. Zum Beispiel könnte ein Datenbankverbindungsfehler mit „failed to connect to database“ umschlossen werden, dann erneut mit „unable to start server“, wodurch eine klare Spur dessen entsteht, was passiert ist und wo.
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Aufgabe
EinfachErstellen Sie ein Dateiverarbeitungssystem, das Fehler mit kontextbezogenen Informationen umschließt (wraps), während sie durch verschiedene Schichten Ihrer Anwendung propagiert werden. Diese Herausforderung zeigt, wie man das %w Format-Verb mit fmt.Errorf verwendet, um Fehlerketten zu erstellen, die den ursprünglichen Fehler bewahren und gleichzeitig aussagekräftigen Kontext hinzufügen.
Sie erhalten zwei Eingaben:
- Einen String, der Details zur Dateioperation im Format
"filename,operation,status"enthält (z. B."config.json,read,permission_denied") - Einen String, der den Systemkontext im Format
"service_name,component"enthält (z. B."UserService,ConfigLoader")
Ihre Aufgabe ist es:
- Die erste Eingabe durch Trennen an den Kommas zu parsen, um den Dateinamen, die Operation und den Status zu erhalten
- Die zweite Eingabe durch Trennen an den Kommas zu parsen, um den Servicenamen und die Komponente zu erhalten
- Einen ursprünglichen Fehler basierend auf dem Status mit
errors.New()zu erstellen:- Wenn der Status
"permission_denied"ist:"permission denied" - Wenn der Status
"not_found"ist:"file not found" - Wenn der Status
"corrupted"ist:"file corrupted" - Für jeden anderen Status:
"unknown error"
- Wenn der Status
- Einen umschlossenen Fehler auf Dateiebene mit
fmt.Errorfund%wzu erstellen:"failed to [operation] file [filename]: %w" - Einen umschlossenen Fehler auf Komponentenebene zu erstellen:
"[component] error: %w" - Einen umschlossenen Fehler auf Serviceebene zu erstellen:
"[service_name] operation failed: %w" - Die Fehlerkette anzuzeigen, indem jede Ebene ausgegeben wird:
"Original error: [original_error_message]""File level: [file_level_error_message]""Component level: [component_level_error_message]""Service level: [service_level_error_message]"
- Eine Zusammenfassung der Fehlerkette anzuzeigen:
"Error Chain Summary:""File: [filename]""Operation: [operation]""Component: [component]""Service: [service_name]""Root cause: [original_error_message]"
Verwenden Sie das strings Paket, um die Eingabestrings an den Kommas zu trennen, das errors Paket, um den ursprünglichen Fehler zu erstellen, und das fmt Paket, um umschlossene Fehler zu erstellen. Diese Herausforderung zeigt, wie das Umschließen von Fehlern mit %w eine klare Spur von Kontext erzeugt, während sich Fehler durch verschiedene Schichten Ihrer Anwendung bewegen, was das Debugging erheblich effektiver macht.
Spickzettel
Error Wrapping ermöglicht es Ihnen, kontextbezogene Informationen zu einem bestehenden Fehler hinzuzufügen, während der ursprüngliche Fehler erhalten bleibt. Verwenden Sie das Format-Verb %w mit fmt.Errorf:
originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)Das Verb %w bewahrt den ursprünglichen Fehler, sodass er später mit Funktionen wie errors.Is und errors.As untersucht werden kann. Dies erzeugt eine Fehlerkette, die den vollständigen Verlauf dessen beibehält, was schiefgelaufen ist, was wertvoll ist, wenn Fehler in größeren Anwendungen mehrere Funktionen durchlaufen.
Probier es selbst
package main
import (
"errors"
"fmt"
"strings"
)
func main() {
// Eingabe lesen
var fileDetails string
var systemContext string
fmt.Scanln(&fileDetails)
fmt.Scanln(&systemContext)
// Eingaben parsen
fileInfo := strings.Split(fileDetails, ",")
filename := fileInfo[0]
operation := fileInfo[1]
status := fileInfo[2]
contextInfo := strings.Split(systemContext, ",")
serviceName := contextInfo[0]
component := contextInfo[1]
// TODO: Schreiben Sie Ihren Code unten
// Erstellen Sie den ursprünglichen Fehler basierend auf dem Status
// Erstellen Sie einen Fehler auf Dateiebene (wrapped error)
// Erstellen Sie einen Fehler auf Komponentenebene (wrapped error)
// Erstellen Sie einen Fehler auf Serviceebene (wrapped error)
// Geben Sie jede Fehlerebene und Zusammenfassung aus
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Ablauf
1Fortgeschrittener Kontrollfluss
Switch mit `fallthrough`Abbrechen von verschachtelten SchleifenFortsetzen einer bestimmten SchleifeDie `goto`-AnweisungZusammenfassung – Fortgeschrittene Schleifensteuerung4Projekt: Einfache Aufgabenliste
Projekt-SetupEine Aufgabe hinzufügen7Fehlerbehandlung im Detail
Benutzerdefinierte FehlertypenFehler-Wrapping mit `%w`Unwrapping mit `errors.Is`Unwrapping mit `errors.As``panic` verstehen`recover` verwendenZusammenfassung – Sichere Division2Structs und Methoden
Methoden für Structs definierenValue ReceiverPointer ReceiverReceiver auswählenMethoden vs. FunktionenZusammenfassung – Struct-Verhalten5Maps im Detail
Maps von StructsPointer als Map-WertePrüfen auf Nil-MapsMaps vergleichenZusammenfassung – Wortfrequenz-Zähler8Projekt: Einfache Bestandsverwaltung
ProjektübersichtLagerbestand prüfen11Abschlussherausforderungen
Einfache KontaktlisteEinfacher Zahlen-ValidatorSammler für eindeutige Elemente3Interfaces (Die Grundlagen)
Was ist ein Interface?Ein Interface definierenEin Interface implementierenInterface-Typen verwendenLeeres InterfaceType AssertionsType SwitchZusammenfassung – Formen und Verhalten