Historia de la pregunta:
Los operadores defer, panic y recover son mecanismos importantes para gestionar el flujo de ejecución en Go. El operador defer se utiliza para la ejecución diferida de funciones, panic inicia un error (terminación de emergencia), y recover permite capturar la emergencia y continuar la ejecución.
Problema:
Sin un uso adecuado de estos mecanismos, es difícil finalizar correctamente los recursos y lograr la resiliencia. La finalización impredecible de una función, recursos no liberados y un "salida" incontrolada de la aplicación ante errores son problemas comunes con un enfoque incorrecto.
Solución:
La aplicación correcta de defer garantiza la liberación segura de recursos incluso en caso de errores. panic es un mecanismo de terminación de emergencia para situaciones excepcionales, que debe usarse solo para casos verdaderamente excepcionales. recover brinda la posibilidad de "salvar" la ejecución dentro de una función diferida.
Ejemplo de código:
func riskyFunction() { defer func() { if r := recover(); r != nil { fmt.Println("Recuperado en riskyFunction:", r) } }() fmt.Println("Haciendo algo de trabajo...") panic("¡sucedió algo malo!") } func main() { riskyFunction() fmt.Println("Después de riskyFunction") }
Características clave:
defer siempre se llama en orden inverso al salir de la función. Incluso durante un panic.recover solo funciona DENTRO de funciones diferidas.panic interrumpe la ejecución de la gorutina actual; si no se captura mediante recover, termina el proceso.¿Por qué recover no funciona fuera de defer dentro de la misma función donde ocurrió panic?
recover devuelve un valor no nulo (es decir, captura el pánico) solo si se llama desde una función defer, anidada en la misma función donde ocurrió el panic. Si se llama recover directamente, siempre devuelve nil.
Ejemplo de código:
func f() { panic("¡fallo!") r := recover() // ¡no funciona! }
¿Se puede llamar defer después de panic y se ejecutará?
No. Después de panic, todas las llamadas defer registradas se ejecutan, pero nuevas defer después de panic no serán llamadas, ya que la ejecución de la función ya está "colapsando".
¿Se puede recuperarse (recover) de un panic que ocurrió en otra gorutina?
No, recover solo funciona para pánicos en la gorutina actual. Si otra gorutina entra en pánico y no se llama recover en esa misma gorutina, la aplicación terminará.
En el proyecto, todos los errores se lanzaban mediante panic, y la recuperación solo se manejaba en la función principal. Esto resultaba en recursos que no se cerraban, parte de los datos perdidos y registros ilegibles.
Ventajas:
Desventajas:
En cada sección crítica se utilizaba defer para liberar recursos, panic se aplicaba solo para situaciones verdaderamente excepcionales, y recover se usaba para aislar emergencias en partes no críticas. Además, se registraban todos los detalles del error.
Ventajas:
Desventajas: