Menu
Coddy logo textTech

Rimuovere il wrapping con `errors.As`

Fa parte della sezione Logica e flusso del percorso GO di Coddy. Lezione 41 di 68.

Mentre errors.Is ti aiuta a identificare specifici valori di errore in una catena, a volte devi accedere ai campi e ai dati effettivi di un tipo di errore personalizzato. La funzione errors.As offre questa possibilità, trovando il primo errore in una catena che corrisponde a un tipo specifico ed estraendolo per esaminarlo.

La funzione errors.As accetta due parametri: l'errore da esaminare e un puntatore a una variabile del tipo di errore target. Se trova un tipo di errore corrispondente nella catena, assegna quell'errore alla tua variabile e restituisce true:

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

Questo è particolarmente efficace quando si lavora con tipi di errore personalizzati che contengono un contesto aggiuntivo. A differenza di errors.Is, che controlla solo l'uguaglianza, errors.As estrae l'istanza effettiva dell'errore, consentendoti di accedere ai suoi campi e metodi. Questo rende la gestione degli errori più sofisticata e informativa nelle applicazioni complesse.

challenge icon

Sfida

Facile

Crea un sistema di gestione degli errori API che utilizzi errors.As per estrarre ed esaminare tipi di errore personalizzati da catene di errori avvolti. Questa sfida mostra come usare errors.As per accedere ai campi e ai dati di specifici tipi di errore personalizzati, anche quando sono stati avvolti con ulteriore contesto.

Riceverai due input:

  • Una stringa contenente i dettagli della richiesta API nel formato "endpoint,method,error_code,error_field" (ad esempio, "/users,POST,400,email")
  • Una stringa contenente il contesto di sistema nel formato "service_name,request_id" (ad esempio, "UserAPI,req_12345")

Il tuo compito è:

  1. Creare un tipo di errore personalizzato chiamato struct APIError con tre campi:
    • Code (int) - il codice di stato HTTP
    • Field (string) - il campo che ha causato l'errore
    • Message (string) - una descrizione dell'errore
  2. Implementare il metodo Error() string per APIError, che restituisca: "API error [code]: [message] (field: [field])"
  3. Analizzare il primo input suddividendolo in corrispondenza delle virgole per ottenere endpoint, method, error code ed error field
  4. Analizzare il secondo input suddividendolo in corrispondenza delle virgole per ottenere il nome del servizio e l'ID della richiesta
  5. Convertire la stringa del codice di errore in un intero
  6. Creare un'istanza di APIError in base al codice di errore:
    • Se il codice è 400: messaggio "invalid request data"
    • Se il codice è 401: messaggio "authentication required"
    • Se il codice è 404: messaggio "resource not found"
    • Se il codice è 500: messaggio "internal server error"
    • Per qualsiasi altro codice: messaggio "unknown error"
  7. Creare un errore avvolto a livello di endpoint usando fmt.Errorf con %w: "[method] [endpoint] failed: %w"
  8. Creare un errore avvolto a livello di servizio: "[service_name] request [request_id] failed: %w"
  9. Usare errors.As per estrarre APIError dalla catena di errori avvolti e mostrare il risultato dell'estrazione:
    • Se l'estrazione riesce: "API error extracted successfully"
    • Se l'estrazione non riesce: "Failed to extract API error"
  10. Se l'estrazione è riuscita, mostrare i dettagli dell'errore estratto:
    • "Extracted Error Details:"
    • "Code: [code]"
    • "Field: [field]"
    • "Message: [message]"
    • "Full error: [full_error_message_from_Error_method]"
  11. Mostrare la catena di errori completa:
    • "Error Chain:"
    • "Original: [original_api_error_message]"
    • "Endpoint level: [endpoint_level_error_message]"
    • "Service level: [service_level_error_message]"
  12. Mostrare un'analisi finale:
    • "Error Analysis:"
    • "Service: [service_name]"
    • "Request ID: [request_id]"
    • "Endpoint: [method] [endpoint]"
    • "HTTP Status: [code]"
    • "Problem Field: [field]"
    • "Error Category: [error_category]", dove error_category è "Client Error" per i codici 400-499, "Server Error" per i codici 500-599 oppure "Unknown" per gli altri codici

Usa il pacchetto strings per suddividere le stringhe di input in corrispondenza delle virgole, il pacchetto strconv per convertire la stringa del codice di errore in un intero, il pacchetto errors per errors.As e il pacchetto fmt per avvolgere gli errori. Questa sfida mostra come errors.As consenta di accedere ai campi e ai metodi specifici dei tipi di errore personalizzati all'interno di catene di errori avvolti, permettendo una gestione e un'analisi sofisticate degli errori.

Provalo tu

package main

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

func main() {
	// Leggi l'input
	var apiDetails string
	var systemContext string
	fmt.Scanln(&apiDetails)
	fmt.Scanln(&systemContext)
	
	// Analizza gli input
	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]
	
	// Converti il codice di errore in un numero intero
	errorCode, _ := strconv.Atoi(errorCodeStr)
	
	// TODO: Scrivi il tuo codice qui sotto
	// 1. Crea la struct APIError con i campi Code, Field e Message
	// 2. Implementa il metodo Error() per APIError
	// 3. Crea un'istanza di APIError in base al codice di errore
	// 4. Crea errori incapsulati (a livello di endpoint e di servizio)
	// 5. Usa errors.As per estrarre APIError dalla catena di errori incapsulati
	// 6. Mostra il risultato dell'estrazione e i dettagli dell'errore
	// 7. Mostra la catena degli errori e l'analisi finale
	
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Logica e flusso

Esercitati da solo: Compilatore Go online