Menu
Coddy logo textTech

Rimuovere il wrapping con `errors.Is`

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

Quando lavori con errori avvolti, ti serve un modo per verificare se un errore specifico è presente in un punto qualsiasi della catena degli errori. La funzione errors.Is fornisce esattamente questa possibilità, consentendoti di identificare gli errori sentinella anche quando sono stati avvolti più volte.

La funzione errors.Is accetta due parametri: l'errore che vuoi esaminare e l'errore di destinazione che stai cercando. Restituisce true se l'errore di destinazione viene trovato in qualsiasi punto della catena degli errori:

var ErrNotFound = errors.New("not found")

wrappedErr := fmt.Errorf("failed to load user: %w", ErrNotFound)

if errors.Is(wrappedErr, ErrNotFound) {
    fmt.Println("This is a not found error")
}

Questo è il modo moderno e consigliato per verificare la presenza di errori specifici in Go. A differenza del confronto tra stringhe o dei controlli di uguaglianza diretta, errors.Is funziona correttamente con gli errori avvolti e segue la catena degli errori per trovare corrispondenze. Questo rende la gestione degli errori robusta e affidabile, anche quando gli errori attraversano più livelli della tua applicazione.

challenge icon

Sfida

Facile

Crea un sistema di monitoraggio delle connessioni al database che utilizza errors.Is per identificare errori di connessione specifici nelle catene di errori avvolti. Questa sfida dimostra come usare errors.Is per rilevare errori sentinella anche quando sono stati avvolti con ulteriore contesto attraverso più livelli applicativi.

Riceverai due input:

  • Una stringa contenente i dettagli dell'operazione sul database nel formato "database_name,operation,error_type" (ad es., "users_db,connect,connection_timeout")
  • Una stringa contenente il contesto dell'applicazione nel formato "service_name,retry_count" (ad es., "AuthService,3")

Il tuo compito è:

  1. Definire tre errori sentinella usando errors.New():
    • ErrConnectionTimeout con il messaggio "connection timeout"
    • ErrConnectionRefused con il messaggio "connection refused"
    • ErrDatabaseNotFound con il messaggio "database not found"
  2. Analizzare il primo input dividendolo in corrispondenza delle virgole per ottenere il nome del database, l'operazione e il tipo di errore
  3. Analizzare il secondo input dividendolo in corrispondenza delle virgole per ottenere il nome del servizio e il numero di tentativi
  4. Creare l'errore originale in base al tipo di errore:
    • Se il tipo di errore è "connection_timeout": usare ErrConnectionTimeout
    • Se il tipo di errore è "connection_refused": usare ErrConnectionRefused
    • Se il tipo di errore è "database_not_found": usare ErrDatabaseNotFound
    • Per qualsiasi altro tipo di errore: usare errors.New("unknown database error")
  5. Creare un errore avvolto a livello del database usando fmt.Errorf con %w: "failed to [operation] database [database_name]: %w"
  6. Creare un errore avvolto a livello del servizio: "[service_name] database operation failed after [retry_count] retries: %w"
  7. Usare errors.Is per verificare se l'errore finale avvolto corrisponde a ciascun errore sentinella e mostrare i risultati:
    • "Checking for connection timeout: [true/false]"
    • "Checking for connection refused: [true/false]"
    • "Checking for database not found: [true/false]"
  8. Mostrare la catena di errori:
    • "Error Chain:"
    • "Original: [original_error_message]"
    • "Database level: [database_level_error_message]"
    • "Service level: [service_level_error_message]"
  9. Mostrare l'analisi dell'errore:
    • "Error Analysis:"
    • "Database: [database_name]"
    • "Operation: [operation]"
    • "Service: [service_name]"
    • "Retries: [retry_count]"
    • "Error type detected: [detected_error_type]" dove detected_error_type è uno tra "Connection Timeout", "Connection Refused", "Database Not Found" o "Unknown Error"

Usa il pacchetto strings per dividere le stringhe di input in corrispondenza delle virgole, il pacchetto errors per gli errori sentinella e errors.Is, e il pacchetto fmt per avvolgere gli errori. Questa sfida dimostra come errors.Is consenta un'identificazione robusta degli errori, che funziona correttamente con gli errori avvolti, rendendola essenziale per una gestione affidabile degli errori nelle applicazioni complesse.

Provalo tu

package main

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

func main() {
	// Leggi l'input
	var dbOperation string
	var appContext string
	fmt.Scanln(&dbOperation)
	fmt.Scanln(&appContext)
	
	// Analizza gli input
	dbParts := strings.Split(dbOperation, ",")
	databaseName := dbParts[0]
	operation := dbParts[1]
	errorType := dbParts[2]
	
	contextParts := strings.Split(appContext, ",")
	serviceName := contextParts[0]
	retryCount := contextParts[1]
	
	// TODO: Scrivi il tuo codice qui sotto
	// 1. Definisci i tre errori sentinella usando errors.New()
	// 2. Crea l'errore originale in base al tipo di errore
	// 3. Crea un errore incapsulato a livello di database usando fmt.Errorf con %w
	// 4. Crea un errore incapsulato a livello di servizio
	// 5. Usa errors.Is per verificare ciascun errore sentinella
	// 6. Mostra i risultati e la catena degli errori
	
}
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