Saltar al contenido principal
eLearner.app
Módulo 6 · Lección 5 de 530/50 en el curso~14 min
Lecciones del módulo (5/5)

La interfaz error

error en Go no es una palabra clave: es una interfaz incorporada con una método único.

Go
type error interface {
    Error() string
}

Todo lo que tenga Error() string es error. Combinado con el convención de devolver (T, error) de funciones, es la fundamento del manejo de errores en Go.

Errores centinela

Go
import "errors"

var ErrNotFound = errors.New("non trovato")

func find(key string) (string, error) {
    // ...
    return "", ErrNotFound
}

Un centinela es un valor error exportado que la persona que llama puede comparar para reconocer un caso de error específico.

Errores personalizados (con datos)

Para transportar contexto (por ejemplo, la clave que falta), define un tipo:

Go
type ErrNotFound struct {
    Key string
}

func (e *ErrNotFound) Error() string {
    return "non trovato: " + e.Key
}

func find(key string) (string, error) {
    return "", &ErrNotFound{Key: key}
}

errores.Es y errores.Como (Go 1.13+)

La comparación con == funciona sólo para centinelas "puros". ser robusto contra errores empaquetados, utilice el paquete errors:

Go
import "errors"

if errors.Is(err, ErrNotFound) {
    // err IS ErrNotFound (even if wrapped)
}

var nfe *ErrNotFound
if errors.As(err, &nfe) {
    // err IS (or wraps) an *ErrNotFound; nfe points to the concrete value
    fmt.Println("chiave mancante:", nfe.Key)
}
  • errors.Is(err, target): verdadero si el objetivo está en algún lugar de la cadena de envoltura.
  • errors.As(err, &target): asigna al objetivo el primer error en la cadena de su tipo.

Envolviendo con %w

Go
if err := find("k"); err != nil {
    return fmt.Errorf("operazione X: %w", err)
}

%w (NO %s o %v) crea un nuevo error que envuelve el original, manteniendo la cadena navegable por errors.Is/As.

Patrón de manejo

Go
v, err := op()
if err != nil {
    return fmt.Errorf("op fallita per %q: %w", id, err)
}

Modismos:

  • Verifique err != nil inmediatamente, no hay "camino feliz temprano".
  • Agregue contexto en cada nivel con fmt.Errorf("... : %w", err).
  • "Upstream" (cerca de main/handler), discrimina con errors.Is/As.

Pruébalo

Ejercicio#go.m6.l5.e1
Intentos: 0Cargando...

Implemente la cadena Error() en *ErrNotFound para que devuelva 'non trovato: <Key>'.

Cargando editor...
Mostrar pista

`fmt.Println(err)` llama automáticamente al método Error() en su estructura.

Solución disponible después de 3 intentos

Ejercicio#go.m6.l5.e2
Intentos: 0Cargando...

Utilice errores. Es para comprobar si err es igual al centinela ErrVuoto.

Cargando editor...
Mostrar pista

`errors.Is(err, target)` es robusto incluso con cadenas envolventes.

Solución disponible después de 3 intentos

Cuestionario#go.m6.l5.e3
Listo

¿Cuál es la firma exacta del método para implementar el error?

Go
func (e *MyErr) ??? {}
Opciones de respuesta

Resumen

  • error = interface { Error() string }, incorporado.
  • Centinelas con errors.New("...") para casos conocidos sin contexto.
  • Tipos de error personalizados con campos para llevar contexto.
  • errors.Is(err, target): comparación robusta con el envoltorio.
  • errors.As(err, &target): extracción del tipo de hormigón.
  • fmt.Errorf("...: %w", err): envoltura que preserva la cadena.
  • Nunca %v / %s para envolver: SIEMPRE use %w.