Lecciones del módulo (5/5)
Errores: el patrón `if err != nil`
En Go, los errores son valores, no excepciones. Una función que puede fail devuelve el error como último valor y la persona que llama lo verifica explícitamente. Es explícito, predecible, fácil de probar; el precio es un poco más de verbosidad.
La interfaz error
error es una pequeña interfaz integrada en el lenguaje:
type error interface {
Error() string
}Cualquier tipo que implemente Error() string es error.
El patrón fundamental
v, err := operazione()
if err != nil {
// gestisci o propaga
return err
}
// usa vVerás esto miles de veces: es el código idiomático de cada llamada falible. No te sientas culpable por la repetición: es una característica, no un error.
Errores de construcción: errors.New y fmt.Errorf
import (
"errors"
"fmt"
)
err1 := errors.New("file mancante")
err2 := fmt.Errorf("apertura %q fallita: permesso negato", path)fmt.Errorf es perfecto cuando quieres incluir variables en el mensaje.
Envolviendo con %w
Para propagar un error agregando contexto SIN perder el original:
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("config: %w", err)
}%w "envuelve" el error original, recuperable más tarde con
errors.Is (igualdad para centinelas) o errors.As (para tipo concreto):
if errors.Is(err, os.ErrNotExist) {
// file inesistente, gestione speciale
}Errores centinela
Estos son errores exportados como variables, utilizados para comparaciones con errors.Is:
var ErrNotFound = errors.New("non trovato")
func find(id int) (Item, error) {
// ...
return Item{}, ErrNotFound
}
// chiamante:
if errors.Is(err, ErrNotFound) { ... }panic y recover (vista previa)
panic existe en Go pero está reservado para errores irrecuperables (por ejemplo, errores,
invariantes violadas), no para el flujo de control normal. Profundizaremos en
el módulo de Funciones con defer/recover. Por ahora: no lo use en su lugar
del patrón if err != nil.
Pruébalo
Maneje el error de strconv.Atoi: si err! = nil, imprímalo y regrese; de lo contrario, imprima n.
Mostrar pista
El patrón canónico: verifique `err != nil`, registre/regrese, luego use `n`.
Solución disponible después de 3 intentos
Implementar safeDiv: si b == 0 devuelve 0 y errores.New('división por cero'); de lo contrario a/b y nulo.
Mostrar pista
Verifique `b == 0` ANTES de la división para evitar el pánico en tiempo de ejecución.
Solución disponible después de 3 intentos
¿Cuál es el patrón idiomático para manejar un error en Go?
v, err := f()
// poi?Resumen
errores una interfaz con un métodoError() string.- Patrón canónico:
v, err := f(); if err != nil { return err }. - Errores de compilación con
errors.New(msg)ofmt.Errorf("ctx: %w", err). - Utilice
%wpara enrollar yerrors.Is/errors.Aspara inspeccionar la cadena. panicsólo para errores irrecuperables, NO para flujo de control normal.