Unwrapping mit `errors.As`
Teil des Abschnitts Logik & Ablauf der GO-Journey von Coddy. Lektion 41 von 68.
Während errors.Is Ihnen hilft, spezifische Fehlerwerte in einer Kette zu identifizieren, müssen Sie manchmal auf die tatsächlichen Felder und Daten eines benutzerdefinierten Fehlertyps zugreifen. Die Funktion errors.As bietet diese Möglichkeit, indem sie den ersten Fehler in einer Kette findet, der einem bestimmten Typ entspricht, und ihn zur Untersuchung extrahiert.
Die Funktion errors.As nimmt zwei Parameter entgegen: den zu untersuchenden Fehler und einen Pointer auf eine Variable des Ziel-Fehlertyps. Wenn sie einen passenden Fehlertyp in der Kette findet, setzt sie Ihre Variable auf diesen Fehler und gibt true zurück:
var validationErr ValidationError
if errors.As(wrappedErr, &validationErr) {
fmt.Printf("Field: %s, Message: %s\n", validationErr.Field, validationErr.Message)
}Dies ist besonders leistungsfähig bei der Arbeit mit benutzerdefinierten Fehlertypen, die zusätzlichen Kontext enthalten. Im Gegensatz zu errors.Is, das nur auf Gleichheit prüft, extrahiert errors.As die tatsächliche Fehlerinstanz, was es Ihnen ermöglicht, auf deren Felder und Methoden zuzugreifen. Dies macht die Fehlerbehandlung in komplexen Anwendungen anspruchsvoller und informativer.
Aufgabe
EinfachErstelle ein API-Fehlerbehandlungssystem, das errors.As verwendet, um benutzerdefinierte Fehlertypen aus verketteten Fehlerketten zu extrahieren und zu untersuchen. Diese Herausforderung zeigt, wie du errors.As verwenden kannst, um auf die Felder und Daten bestimmter benutzerdefinierter Fehlertypen zuzugreifen, selbst wenn diese mit zusätzlichem Kontext umschlossen wurden.
Du erhältst zwei Eingaben:
- Eine Zeichenkette mit API-Anfragedetails im Format
"endpoint,method,error_code,error_field"(z. B."/users,POST,400,email") - Eine Zeichenkette mit Systemkontext im Format
"service_name,request_id"(z. B."UserAPI,req_12345")
Deine Aufgabe ist es:
- Einen benutzerdefinierten Fehlertyp namens
APIErrorstruct mit drei Feldern zu erstellen:Code(int) – der HTTP-StatuscodeField(string) – das Feld, das den Fehler verursacht hatMessage(string) – eine Beschreibung des Fehlers
- Die Methode
Error() stringfürAPIErrorzu implementieren, die Folgendes zurückgibt:"API error [code]: [message] (field: [field])" - Die erste Eingabe durch Aufteilen an Kommas zu analysieren, um Endpoint, Methode, Fehlercode und Fehlerfeld zu erhalten
- Die zweite Eingabe durch Aufteilen an Kommas zu analysieren, um Servicenamen und Anfrage-ID zu erhalten
- Die Fehlercode-Zeichenkette in eine Ganzzahl umzuwandeln
- Eine
APIError-Instanz basierend auf dem Fehlercode zu erstellen:- Wenn der Code 400 ist: Nachricht
"invalid request data" - Wenn der Code 401 ist: Nachricht
"authentication required" - Wenn der Code 404 ist: Nachricht
"resource not found" - Wenn der Code 500 ist: Nachricht
"internal server error" - Für jeden anderen Code: Nachricht
"unknown error"
- Wenn der Code 400 ist: Nachricht
- Einen umschlossenen Fehler auf Endpoint-Ebene mit
fmt.Errorfund%wzu erstellen:"[method] [endpoint] failed: %w" - Einen umschlossenen Fehler auf Service-Ebene zu erstellen:
"[service_name] request [request_id] failed: %w" errors.Aszu verwenden, um denAPIErroraus der umschlossenen Fehlerkette zu extrahieren und das Ergebnis der Extraktion anzuzeigen:- Wenn die Extraktion erfolgreich ist:
"API error extracted successfully" - Wenn die Extraktion fehlschlägt:
"Failed to extract API error"
- Wenn die Extraktion erfolgreich ist:
- Wenn die Extraktion erfolgreich war, die Details des extrahierten Fehlers anzuzeigen:
"Extracted Error Details:""Code: [code]""Field: [field]""Message: [message]""Full error: [full_error_message_from_Error_method]"
- Die vollständige Fehlerkette anzuzeigen:
"Error Chain:""Original: [original_api_error_message]""Endpoint level: [endpoint_level_error_message]""Service level: [service_level_error_message]"
- Eine abschließende Analyse anzuzeigen:
"Error Analysis:""Service: [service_name]""Request ID: [request_id]""Endpoint: [method] [endpoint]""HTTP Status: [code]""Problem Field: [field]""Error Category: [error_category]", wobei error_category für Codes von 400–499 "Client Error", für Codes von 500–599 "Server Error" und für andere Codes "Unknown" ist
Verwende das Paket strings, um die Eingabezeichenketten an Kommas aufzuteilen, das Paket strconv, um die Fehlercode-Zeichenkette in eine Ganzzahl umzuwandeln, das Paket errors für errors.As und das Paket fmt zum Umschließen von Fehlern. Diese Herausforderung zeigt, wie errors.As dir ermöglicht, auf die spezifischen Felder und Methoden benutzerdefinierter Fehlertypen innerhalb umschlossener Fehlerketten zuzugreifen, wodurch eine anspruchsvolle Fehlerbehandlung und -analyse ermöglicht wird.
Probier es selbst
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
func main() {
// Eingabe lesen
var apiDetails string
var systemContext string
fmt.Scanln(&apiDetails)
fmt.Scanln(&systemContext)
// Eingaben parsen
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]
// Fehlercode in Ganzzahl umwandeln
errorCode, _ := strconv.Atoi(errorCodeStr)
// TODO: Schreiben Sie Ihren Code unten
// 1. APIError-Struktur mit den Feldern Code, Field, Message erstellen
// 2. Error()-Methode für APIError implementieren
// 3. APIError-Instanz basierend auf dem Fehlercode erstellen
// 4. Eingepackte Fehler erstellen (Endpunkt-Ebene und Service-Ebene)
// 5. errors.As verwenden, um APIError aus der Kette der eingepackten Fehler zu extrahieren
// 6. Extraktionsergebnis und Fehlerdetails anzeigen
// 7. Fehlerkette und abschließende Analyse anzeigen
}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Übe selbstständig: Online-Go-Compiler