Désenvelopper avec `errors.As`
Fait partie de la section Logique & Flux du Journey GO de Coddy. Leçon 41 sur 68.
Alors que errors.Is vous aide à identifier des valeurs d'erreur spécifiques dans une chaîne, vous avez parfois besoin d'accéder aux champs et aux données réels d'un type d'erreur personnalisé. La fonction errors.As offre cette possibilité en trouvant la première erreur dans une chaîne qui correspond à un type spécifique et en l'extrayant pour inspection.
La fonction errors.As prend deux paramètres : l'erreur à examiner et un pointeur vers une variable du type d'erreur cible. Si elle trouve un type d'erreur correspondant dans la chaîne, elle affecte cette erreur à votre variable et renvoie true :
var validationErr ValidationError
if errors.As(wrappedErr, &validationErr) {
fmt.Printf("Field: %s, Message: %s\n", validationErr.Field, validationErr.Message)
}Ceci est particulièrement puissant lors de l'utilisation de types d'erreurs personnalisés qui contiennent un contexte supplémentaire. Contrairement à errors.Is qui vérifie uniquement l'égalité, errors.As extrait l'instance d'erreur réelle, vous permettant d'accéder à ses champs et méthodes. Cela rend la gestion des erreurs plus sophistiquée et informative dans les applications complexes.
Défi
FacileConstruisez un système de gestion des erreurs d’API qui utilise errors.As pour extraire et examiner des types d’erreurs personnalisés à partir de chaînes d’erreurs encapsulées. Ce défi montre comment utiliser errors.As pour accéder aux champs et aux données de types d’erreurs personnalisés spécifiques, même lorsqu’ils ont été encapsulés avec un contexte supplémentaire.
Vous recevrez deux entrées :
- Une chaîne contenant les détails de la requête API au format
"endpoint,method,error_code,error_field"(par exemple,"/users,POST,400,email") - Une chaîne contenant le contexte système au format
"service_name,request_id"(par exemple,"UserAPI,req_12345")
Votre tâche consiste à :
- Créer un type d’erreur personnalisé appelé structure
APIErroravec trois champs :Code(int) - le code d’état HTTPField(string) - le champ à l’origine de l’erreurMessage(string) - une description de l’erreur
- Implémenter la méthode
Error() stringpourAPIError, qui renvoie :"API error [code]: [message] (field: [field])" - Analyser la première entrée en la séparant sur les virgules afin d’obtenir le point de terminaison, la méthode, le code d’erreur et le champ d’erreur
- Analyser la deuxième entrée en la séparant sur les virgules afin d’obtenir le nom du service et l’ID de requête
- Convertir la chaîne du code d’erreur en entier
- Créer une instance de
APIErroren fonction du code d’erreur :- Si le code est 400 : message
"invalid request data" - Si le code est 401 : message
"authentication required" - Si le code est 404 : message
"resource not found" - Si le code est 500 : message
"internal server error" - Pour tout autre code : message
"unknown error"
- Si le code est 400 : message
- Créer une erreur encapsulée au niveau du point de terminaison à l’aide de
fmt.Errorfavec%w:"[method] [endpoint] failed: %w" - Créer une erreur encapsulée au niveau du service :
"[service_name] request [request_id] failed: %w" - Utiliser
errors.Aspour extraireAPIErrorde la chaîne d’erreurs encapsulées et afficher le résultat de l’extraction :- Si l’extraction réussit :
"API error extracted successfully" - Si l’extraction échoue :
"Failed to extract API error"
- Si l’extraction réussit :
- Si l’extraction a réussi, afficher les détails de l’erreur extraite :
"Extracted Error Details:""Code: [code]""Field: [field]""Message: [message]""Full error: [full_error_message_from_Error_method]"
- Afficher la chaîne complète des erreurs :
"Error Chain:""Original: [original_api_error_message]""Endpoint level: [endpoint_level_error_message]""Service level: [service_level_error_message]"
- Afficher une analyse finale :
"Error Analysis:""Service: [service_name]""Request ID: [request_id]""Endpoint: [method] [endpoint]""HTTP Status: [code]""Problem Field: [field]""Error Category: [error_category]"où error_category vaut "Client Error" pour les codes 400-499, "Server Error" pour les codes 500-599 ou "Unknown" pour les autres codes
Utilisez le package strings pour séparer les chaînes d’entrée sur les virgules, le package strconv pour convertir la chaîne du code d’erreur en entier, le package errors pour errors.As et le package fmt pour l’encapsulation des erreurs. Ce défi montre comment errors.As permet d’accéder aux champs et aux méthodes spécifiques de types d’erreurs personnalisés au sein de chaînes d’erreurs encapsulées, ce qui permet une gestion et une analyse sophistiquées des erreurs.
Essayez vous-même
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
func main() {
// Lire l'entrée
var apiDetails string
var systemContext string
fmt.Scanln(&apiDetails)
fmt.Scanln(&systemContext)
// Analyser les entrées
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]
// Convertir le code d'erreur en entier
errorCode, _ := strconv.Atoi(errorCodeStr)
// TODO: Écrivez votre code ci-dessous
// 1. Créer la structure APIError avec les champs Code, Field, Message
// 2. Implémenter la méthode Error() pour APIError
// 3. Créer une instance d'APIError basée sur le code d'erreur
// 4. Créer des erreurs enveloppées (au niveau de l'endpoint et du service)
// 5. Utiliser errors.As pour extraire APIError de la chaîne d'erreurs enveloppées
// 6. Afficher le résultat de l'extraction et les détails de l'erreur
// 7. Afficher la chaîne d'erreurs et l'analyse finale
}Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Logique & Flux
1Structures de contrôle avancées
Switch avec `fallthrough`Sortir de boucles imbriquéesContinuer une boucle spécifiqueL'instruction `goto`Récapitulatif - Contrôle de boucle avancé4Projet : Liste de tâches simple
Configuration du projetAjouter une tâche7Gestion des erreurs en profondeur
Types d'erreurs personnalisésEnvelopper des erreurs avec `%w`Désenvelopper avec `errors.Is`Désenvelopper avec `errors.As`Comprendre `panic`Utiliser `recover`Récapitulatif - Division sécurisée2Structures et Méthodes
Définir des méthodes sur des structuresReceveurs par valeurReceveurs par pointeurChoisir les receveursMéthodes vs FonctionsRécapitulatif - Comportement des structures5Les Maps en profondeur
Maps de StructsPointeurs comme valeurs de MapTester les Maps NilComparer des MapsRécapitulatif - Compteur de fréquence de mots3Interfaces (Les bases)
Qu'est-ce qu'une Interface ?Définir une InterfaceImplémenter une InterfaceUtiliser les types d'InterfaceInterface videAssertions de typeType SwitchRécapitulatif - Formes et comportementsEntraînez-vous par vous-même : Compilateur Go en ligne