ProgrammazioneSviluppatore Go

Come funziona la gestione degli errori (errors) in Go: quali approcci esistono per la gestione, perché gli errori vengono restituiti anziché lanciati e come implementare propri tipi di errori?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In Go, l'approccio standard per la gestione degli errori consiste nel restituire un valore di tipo error dalla funzione. A differenza dei linguaggi con eccezioni, in Go le eccezioni (panic, recover) vengono utilizzate solo per situazioni veramente eccezionali; per la logica di business si dovrebbero utilizzare errori normali.

Il modo classico:

func doSomething() error { // ... return nil // o errors.New("some error") } err := doSomething() if err != nil { // gestione dell'errore }

È possibile creare propri tipi di errore per un'analisi più dettagliata:

type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("(%d) %s", e.Code, e.Message) } err := &MyError{404, "not found"}

Controllo tipico di un errore specifico:

if myErr, ok := err.(*MyError); ok && myErr.Code == 404 { // gestione dell'errore 404 }

Domanda ingannevole.

È possibile confrontare error con nil usando == in Go?

Risposta: Sì, è possibile e necessario, per controllare l'assenza di errori. Ma è importante ricordare: se l'errore è stato avvolto o creato usando errori che contengono nil all'interno delle strutture, il confronto potrebbe essere errato. Ad esempio:

var err error = (*MyError)(nil) fmt.Println(err == nil) // false!

L'errore si verifica perché l'interfaccia non è uguale a nil, se il suo tipo non è nil, anche se il valore interno è nil.

Esempi di errori reali dovuti alla mancanza di conoscenza delle sottigliezze dell'argomento.


Storia

Il microservizio era impegnato nella registrazione degli errori mediante il confronto con nil. Uno degli sviluppatori restituiva un errore tipizzato come (*MyError)(nil), non rendendosi conto che questo non è equivalente a nil (l'interfaccia non è nil). Di conseguenza, la gestione degli errori ha smesso di funzionare, e molte false allerta sono finite nelle metriche.


Storia

Nel progetto, invece di passare l'errore a catena, veniva usato panic per tutti gli errori, ritenendo che fosse un modo "pulito". Questo ha portato al crash dell'applicazione ad ogni input non valido dell'utente, poiché panic/recover non sono destinati alla logica di business continua.


Storia

L'errore è stato avvolto più volte usando fmt.Errorf("some: %w", err), ma durante il controllo su un tipo specifico di errore veniva effettuato un confronto normale, invece di utilizzare errors.Is e errors.As. Questo portava al fatto che la logica di business non reagiva ai tipi di errore personalizzati, anche se erano realmente presenti all'interno dell'errore avvolto.