En este tema, aprenderemos sobre dos mecanismos importantes en Go para el manejo de errores y situaciones excepcionales: panic
y recover
. Estos mecanismos permiten manejar errores de una manera controlada y segura, especialmente en situaciones críticas donde la ejecución del programa no puede continuar normalmente.
¿Qué es panic
?
panic
es una función incorporada en Go que se utiliza para detener la ejecución normal de un programa. Cuando se llama a panic
, el programa imprime un mensaje de error y comienza a desenrollar la pila de llamadas, ejecutando las funciones defer
en el camino. Finalmente, el programa se detiene.
Ejemplo de panic
package main import "fmt" func main() { fmt.Println("Inicio del programa") causePanic() fmt.Println("Fin del programa") // Esta línea no se ejecutará } func causePanic() { fmt.Println("Antes del pánico") panic("¡Algo salió mal!") fmt.Println("Después del pánico") // Esta línea no se ejecutará }
Explicación:
- La función
causePanic
llama apanic
con un mensaje de error. - Una vez que se llama a
panic
, el programa imprime el mensaje de error y comienza a desenrollar la pila de llamadas. - Las líneas de código después de
panic
no se ejecutan.
¿Qué es recover
?
recover
es una función incorporada que permite recuperar el control de un programa que ha entrado en pánico. recover
solo funciona dentro de una función defer
. Si se llama a recover
y no hay un pánico en curso, recover
devuelve nil
.
Ejemplo de recover
package main import "fmt" func main() { fmt.Println("Inicio del programa") safeFunction() fmt.Println("Fin del programa") // Esta línea se ejecutará } func safeFunction() { defer func() { if r := recover(); r != nil { fmt.Println("Recuperado del pánico:", r) } }() causePanic() fmt.Println("Después de causePanic") // Esta línea no se ejecutará } func causePanic() { fmt.Println("Antes del pánico") panic("¡Algo salió mal!") fmt.Println("Después del pánico") // Esta línea no se ejecutará }
Explicación:
- La función
safeFunction
utilizadefer
para definir una función anónima que llama arecover
. - Si
causePanic
provoca un pánico,recover
captura el pánico y permite que el programa continúe ejecutándose. - El mensaje "Recuperado del pánico" se imprime, y el programa no se detiene abruptamente.
Ejercicio Práctico
Ejercicio 1: Manejo de Pánico en una Función
Escribe una función llamada divide
que tome dos enteros y devuelva el resultado de la división. Si el divisor es cero, la función debe provocar un pánico. Luego, escribe una función safeDivide
que utilice recover
para manejar el pánico y devolver un error en lugar de detener el programa.
package main import ( "errors" "fmt" ) func main() { result, err := safeDivide(10, 0) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Resultado:", result) } } func divide(a, b int) int { if b == 0 { panic("división por cero") } return a / b } func safeDivide(a, b int) (result int, err error) { defer func() { if r := recover(); r != nil { err = errors.New(fmt.Sprint(r)) } }() result = divide(a, b) return }
Explicación:
- La función
divide
provoca un pánico si el divisor es cero. - La función
safeDivide
utilizadefer
yrecover
para manejar el pánico y devolver un error en lugar de detener el programa.
Ejercicio 2: Implementación de un Servidor Web Seguro
Escribe un servidor web simple que maneje las solicitudes HTTP. Si ocurre un pánico durante el manejo de una solicitud, el servidor debe recuperarse y devolver un mensaje de error al cliente en lugar de detenerse.
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/", safeHandler) fmt.Println("Servidor escuchando en http://localhost:8080") http.ListenAndServe(":8080", nil) } func safeHandler(w http.ResponseWriter, r *http.Request) { defer func() { if r := recover(); r != nil { http.Error(w, "Ocurrió un error interno", http.StatusInternalServerError) } }() handler(w, r) } func handler(w http.ResponseWriter, r *http.Request) { panic("¡Algo salió mal en el servidor!") fmt.Fprintln(w, "Hola, mundo") }
Explicación:
- La función
safeHandler
utilizadefer
yrecover
para manejar cualquier pánico que ocurra enhandler
. - Si
handler
provoca un pánico,recover
captura el pánico y devuelve un mensaje de error al cliente.
Conclusión
En esta sección, hemos aprendido sobre los mecanismos panic
y recover
en Go. panic
se utiliza para manejar situaciones críticas donde la ejecución del programa no puede continuar normalmente, mientras que recover
permite recuperar el control del programa y manejar el error de manera segura. Estos mecanismos son esenciales para escribir programas robustos y confiables en Go.
En el próximo módulo, exploraremos la concurrencia en Go, comenzando con las goroutines.
Curso de Programación en Go
Módulo 1: Introducción a Go
- Introducción a Go
- Configuración del Entorno de Go
- Tu Primer Programa en Go
- Sintaxis y Estructura Básica
Módulo 2: Conceptos Básicos
Módulo 3: Estructuras de Datos Avanzadas
Módulo 4: Manejo de Errores
Módulo 5: Concurrencia
Módulo 6: Temas Avanzados
Módulo 7: Desarrollo Web con Go
Módulo 8: Trabajando con Bases de Datos
Módulo 9: Despliegue y Mantenimiento
- Construcción y Despliegue de Aplicaciones Go
- Registro de Logs
- Monitoreo y Optimización de Rendimiento
- Mejores Prácticas de Seguridad