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.
Sfida
FacileCrea 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 è:
- Definire tre errori sentinella usando
errors.New():ErrConnectionTimeoutcon il messaggio"connection timeout"ErrConnectionRefusedcon il messaggio"connection refused"ErrDatabaseNotFoundcon il messaggio"database not found"
- Analizzare il primo input dividendolo in corrispondenza delle virgole per ottenere il nome del database, l'operazione e il tipo di errore
- Analizzare il secondo input dividendolo in corrispondenza delle virgole per ottenere il nome del servizio e il numero di tentativi
- Creare l'errore originale in base al tipo di errore:
- Se il tipo di errore è
"connection_timeout": usareErrConnectionTimeout - Se il tipo di errore è
"connection_refused": usareErrConnectionRefused - Se il tipo di errore è
"database_not_found": usareErrDatabaseNotFound - Per qualsiasi altro tipo di errore: usare
errors.New("unknown database error")
- Se il tipo di errore è
- Creare un errore avvolto a livello del database usando
fmt.Errorfcon%w:"failed to [operation] database [database_name]: %w" - Creare un errore avvolto a livello del servizio:
"[service_name] database operation failed after [retry_count] retries: %w" - Usare
errors.Isper 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]"
- Mostrare la catena di errori:
"Error Chain:""Original: [original_error_message]""Database level: [database_level_error_message]""Service level: [service_level_error_message]"
- 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
}Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Logica e flusso
1Flusso di controllo avanzato
Switch con `fallthrough`Uscire dai cicli annidatiContinuare un ciclo specificoL'istruzione `goto`Riepilogo - Controllo avanzato dei cicli4Progetto: semplice lista di attività
Configurazione del progettoAggiungere un’attività7Gestione degli errori in dettaglio
Tipi di errore personalizzatiAvvolgere gli errori con `%w`Rimuovere il wrapping con `errors.Is`Rimuovere il wrapping con `errors.As`Capire `panic`Usare `recover`Riepilogo - Divisione sicura2Struct e metodi
Definire metodi sugli structReceiver per valoreReceiver con puntatoreScegliere i receiverMetodi vs funzioniRiepilogo - comportamento degli struct5Mappe in dettaglio
Mappe di structPuntatori come valori delle mappeVerificare le mappe nilConfrontare le mappeRiepilogo - Contatore della frequenza delle parole3Interfacce (le basi)
Che cos’è un’interfaccia?Definire un’interfacciaImplementare un’interfacciaUsare i tipi interfacciaInterfaccia vuotaAsserzioni di tipoSwitch di tipoRiepilogo: forme e comportamentiEsercitati da solo: Compilatore Go online