Menu
Coddy logo textTech

Avvolgere gli errori con `%w`

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

Quando si verificano errori nella tua applicazione, spesso hanno bisogno di un contesto aggiuntivo mentre risalgono i diversi livelli del tuo codice. Go fornisce un potente meccanismo per farlo tramite l’incapsulamento degli errori, usando il verbo di formattazione %w con fmt.Errorf.

L’avvolgimento degli errori permette di aggiungere informazioni contestuali a un errore esistente, preservando al contempo l’errore originale sottostante. Questo crea una catena di errori che conserva la cronologia completa di ciò che è andato storto:

originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)

Il verbo %w è speciale: indica a fmt.Errorf di avvolgere l’errore anziché limitarsi a convertirlo in una stringa. In questo modo l’errore originale viene preservato e può essere esaminato in seguito usando funzioni come errors.Is ed errors.As.

Questo schema è particolarmente utile nelle applicazioni più grandi, dove un errore potrebbe passare attraverso più funzioni, ognuna delle quali aggiunge il proprio contesto. Per esempio, un errore di connessione al database potrebbe essere racchiuso in "failed to connect to database", poi nuovamente in "unable to start server", creando una traccia chiara di ciò che è successo e dove.

challenge icon

Sfida

Facile

Costruisci un sistema di elaborazione dei file che avvolga gli errori con informazioni contestuali mentre si propagano attraverso i diversi livelli della tua applicazione. Questa sfida mostra come usare il verbo di formattazione %w con fmt.Errorf per creare catene di errori che conservano l'errore originale aggiungendo al contempo un contesto significativo.

Riceverai due input:

  • Una stringa contenente i dettagli dell'operazione sul file nel formato "filename,operation,status" (ad es., "config.json,read,permission_denied")
  • Una stringa contenente il contesto del sistema nel formato "service_name,component" (ad es., "UserService,ConfigLoader")

Il tuo compito è:

  1. Analizzare il primo input separandolo in corrispondenza delle virgole per ottenere il nome del file, l'operazione e lo stato
  2. Analizzare il secondo input separandolo in corrispondenza delle virgole per ottenere il nome del servizio e il componente
  3. Creare un errore originale in base allo stato usando errors.New():
    • Se lo stato è "permission_denied": "permission denied"
    • Se lo stato è "not_found": "file not found"
    • Se lo stato è "corrupted": "file corrupted"
    • Per qualsiasi altro stato: "unknown error"
  4. Creare un errore avvolto a livello del file usando fmt.Errorf con %w: "failed to [operation] file [filename]: %w"
  5. Creare un errore avvolto a livello del componente: "[component] error: %w"
  6. Creare un errore avvolto a livello del servizio: "[service_name] operation failed: %w"
  7. Visualizzare la catena di errori stampando ogni livello:
    • "Original error: [original_error_message]"
    • "File level: [file_level_error_message]"
    • "Component level: [component_level_error_message]"
    • "Service level: [service_level_error_message]"
  8. Visualizzare un riepilogo della catena di errori:
    • "Error Chain Summary:"
    • "File: [filename]"
    • "Operation: [operation]"
    • "Component: [component]"
    • "Service: [service_name]"
    • "Root cause: [original_error_message]"

Usa il pacchetto strings per separare le stringhe di input in corrispondenza delle virgole, il pacchetto errors per creare l'errore originale e il pacchetto fmt per creare gli errori avvolti. Questa sfida mostra come avvolgere gli errori con %w crei una traccia chiara del contesto mentre gli errori attraversano i diversi livelli della tua applicazione, rendendo il debug molto più efficace.

Provalo tu

package main

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

func main() {
	// Leggi l'input
	var fileDetails string
	var systemContext string
	fmt.Scanln(&fileDetails)
	fmt.Scanln(&systemContext)
	
	// Analizza gli input
	fileInfo := strings.Split(fileDetails, ",")
	filename := fileInfo[0]
	operation := fileInfo[1]
	status := fileInfo[2]
	
	contextInfo := strings.Split(systemContext, ",")
	serviceName := contextInfo[0]
	component := contextInfo[1]
	
	// TODO: Scrivi il tuo codice qui sotto
	// Crea l'errore originale in base a status
	// Crea un errore incapsulato a livello di file
	// Crea un errore incapsulato a livello di componente
	// Crea un errore incapsulato a livello di servizio
	// Stampa ogni livello di errore e il riepilogo
	
}
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