In Go ist der Standardansatz die Fehlerbehandlung über den Rückgabewert error. Dies ermöglicht eine explizite Kontrolle darüber, was bei einem Fehler an jedem Punkt zu tun ist. Panic ist ein Mechanismus zur Handhabung unvorhergesehener katastrophaler Situationen: Sie unterbricht die Ausführung bis zum nächsten defer, wo recover verwendet werden kann, um zu "retten". Aber recover funktioniert nur innerhalb von defer.
Beste Praktiken:
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 }
Kann man jede Panikfehler mit recover an jedem Ort im Programm "fangen"?
Antwort: Nein, recover funktioniert nur innerhalb von defer und nur in der gleichen Goroutine, in der die Panic aufgerufen wurde. In anderen Fällen wird die Panic die Ausführung dieser (oder aller) Goroutines beenden — dies wird oft zur Überraschung.
Geschichte
In der REST-API wurde panic zur Behandlung normaler Fehler in der Business-Logik verwendet. Dies führte zu nicht offensichtlichen Abstürzen der Anwendung und inkorrekten Protokollen, da recover nicht immer korrekt abgerufen wurde.
Geschichte
Im Zahlungsdienst wurde ein defer + recover in der Hauptfunktion implementiert, um alle Paniken zu "fangen", aber man vergaß die Goroutines — in den Tochter-Goroutines fiel die Anwendung ohne defer/recover mit "schrecklichen" Fehlern ab und ließ einen Teil der Transaktionen in inkonsistentem Zustand.
Geschichte
Im Parser komplexer Strukturen wurde vergessen, einen Fehler zurückzugeben, und stattdessen auf panic gewechselt — dies erschwerte die Wartung und das Testen, und es musste die Fehlerbehandlung vollständig neu geschrieben werden, um detailliertes Logging und eine korrekte UX zu haben.