Menu
Coddy logo textTech

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.

quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

challenge icon

Défi

Facile

Construisez 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 enveloppées (wrapped). Ce défi dé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é enveloppé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 du système au format "service_name,request_id" (par exemple, "UserAPI,req_12345")

Votre tâche consiste à :

  1. Créer un type d'erreur personnalisé appelé struct APIError avec trois champs :
    • Code (int) - le code d'état HTTP
    • Field (string) - le champ qui a causé l'erreur
    • Message (string) - une description de l'erreur
  2. Implémenter la méthode Error() string pour APIError qui retourne : "API error [code]: [message] (field: [field])"
  3. Analyser la première entrée en la divisant par les virgules pour obtenir l'endpoint, la méthode, le code d'erreur et le champ d'erreur
  4. Analyser la seconde entrée en la divisant par les virgules pour obtenir le nom du service et l'ID de la requête
  5. Convertir la chaîne du code d'erreur en un entier
  6. Créer une instance de APIError basée sur le 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"
  7. Créer une erreur enveloppée au niveau de l'endpoint en utilisant fmt.Errorf avec %w : "[method] [endpoint] failed: %w"
  8. Créer une erreur enveloppée au niveau du service : "[service_name] request [request_id] failed: %w"
  9. Utiliser errors.As pour extraire l'APIError de la chaîne d'erreurs enveloppé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"
  10. 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]"
  11. Afficher la chaîne d'erreurs complète :
    • "Error Chain:"
    • "Original: [original_api_error_message]"
    • "Endpoint level: [endpoint_level_error_message]"
    • "Service level: [service_level_error_message]"
  12. 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 est "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 diviser 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'enveloppement d'erreurs. Ce défi démontre comment errors.As vous permet d'accéder aux champs et méthodes spécifiques des types d'erreurs personnalisés au sein des chaînes d'erreurs enveloppées, permettant ainsi une gestion et une analyse sophistiquées des erreurs.

Aide-mémoire

La fonction errors.As extrait des types d'erreurs spécifiques à partir de chaînes d'erreurs, permettant l'accès aux champs et méthodes d'erreurs personnalisés.

errors.As prend deux paramètres : l'erreur à examiner et un pointeur vers une variable du type d'erreur cible :

var validationErr ValidationError
if errors.As(wrappedErr, &validationErr) {
    fmt.Printf("Field: %s, Message: %s\n", validationErr.Field, validationErr.Message)
}

Contrairement à errors.Is qui vérifie uniquement l'égalité, errors.As extrait l'instance d'erreur réelle, permettant l'accès à ses champs et méthodes pour une gestion d'erreurs plus sophistiquée.

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
	
}
quiz iconTestez-vous

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