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
causePanicllama apaniccon 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
panicno 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
safeFunctionutilizadeferpara definir una función anónima que llama arecover. - Si
causePanicprovoca un pánico,recovercaptura 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
divideprovoca un pánico si el divisor es cero. - La función
safeDivideutilizadeferyrecoverpara 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
safeHandlerutilizadeferyrecoverpara manejar cualquier pánico que ocurra enhandler. - Si
handlerprovoca un pánico,recovercaptura 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
