ProgrammazioneSviluppatore Backend

Fornire un confronto dettagliato tra panic/recover e la gestione degli errori standard in Go: differenze, migliori pratiche, insidie. Quando è giustificato utilizzare panic?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In Go, l'approccio standard è la gestione degli errori tramite il valore restituito error. Questo consente di controllare esplicitamente cosa fare in caso di errore in ogni punto. Panic è un meccanismo per gestire situazioni catastrofiche impreviste: interrompe l'esecuzione fino al defer più vicino, dove si può usare recover per "salvare". Tuttavia, recover funziona solo all'interno di defer.

Migliori pratiche:

  • Utilizzare error per situazioni normali e errori attesi (file non trovato, richiesta non valida).
  • Panic — solo per guasti critici, quando è impossibile continuare a lavorare (ad esempio, violazione di invarianti, errore di inizializzazione).
  • Non utilizzare mai panic per il normale flow (ad esempio, per la validazione dei dati).
func safeDivide(a, b int) (int, error) { if b == 0 { return 0, errors.New("divide by zero") } return a/b, nil } func mustDivide(a, b int) int { if b == 0 { panic("divide by zero!") } return a/b }

Domanda insidiosa.

È possibile "catturare" qualsiasi errore di panico con recover in qualsiasi parte del programma?

Risposta: No, recover funzionerà solo all'interno di defer e solo nella stessa goroutine in cui è stato chiamato panic. Negli altri casi, panic terminerà l'esecuzione di questa (o di tutte) le goroutine — questo spesso risulta essere una sorpresa.

Esempi di errori reali dovuti all'ignoranza delle sottigliezze dell'argomento.


Storia

Nell'API REST si utilizzava panic per gestire errori normali nella logica di business. Questo ha portato a crash imprevisti dell'applicazione e log non corretti, poiché recover non funzionava sempre correttamente.


Storia

Nel servizio di elaborazione dei pagamenti è stata implementata defer + recover nella funzione principale, per "catturare" tutti i panic, ma si è dimenticati delle goroutine — nelle goroutine figlie, senza defer/recover, l'applicazione è crollata con errori "terribili", lasciando parte delle transazioni in uno stato incoerente.


Storia

Nel parser di strutture complesse si è dimenticato di restituire l'errore, sostituendolo con panic — questo ha complicato la manutenzione e il testing, costringendo a riscrivere completamente la gestione degli errori per avere un logging dettagliato e una UX corretta.