Creación de errores personalizados
errors.New, fmt.Errorf y errores centinela
Creación de errores personalizados es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.
¿Por qué utilizar tipos de error personalizados?
Los tipos de error personalizados contienen datos estructurados además de un mensaje de texto, lo que permite a los llamadores inspeccionar y reaccionar ante condiciones de error específicas:
package main
import "fmt"
// Custom error type carries extra context
type HTTPError struct {
StatusCode int
Message string
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("HTTP %d: %s", e.StatusCode, e.Message)
}
func fetch(url string) error {
return &HTTPError{404, "page not found"}
}
func main() {
err := fetch("http://example.com")
fmt.Println(err) // HTTP 404: page not found
}Implementar la interfaz error
Cualquier tipo que tenga un método Error() string satisface error:
package main
import "fmt"
type ValidationError struct {
Field string
Value interface{}
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation: field %q value %v — %s", e.Field, e.Value, e.Message)
}
func validateAge(age int) error {
if age < 0 || age > 150 {
return &ValidationError{"age", age, "must be between 0 and 150"}
}
return nil
}
func main() {
fmt.Println(validateAge(-5))
}Errores centinela con errors.New
Los errores centinela son variables a nivel de paquete para condiciones de error conocidas:
package main
import ("fmt"; "errors")
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrAlreadyExists = errors.New("already exists")
)
func getUser(id int) (string, error) {
if id != 1 { return "", ErrNotFound }
return "Alice", nil
}
func main() {
_, err := getUser(99)
if errors.Is(err, ErrNotFound) {
fmt.Println("user does not exist")
}
}fmt.Errorf con %w para envolver errores
fmt.Errorf con %w envuelve un error y conserva el original para errors.Is y errors.As:
package main
import ("fmt"; "errors")
var ErrDatabase = errors.New("database error")
func queryDB() error {
return fmt.Errorf("queryDB: %w", ErrDatabase)
}
func main() {
err := queryDB()
fmt.Println(err) // queryDB: database error
fmt.Println(errors.Is(err, ErrDatabase)) // true — unwrapped
}Error personalizado con Unwrap
Implemente Unwrap() error en su tipo de error personalizado para que participe en las cadenas de errores:
package main
import ("fmt"; "errors")
var ErrNotFound = errors.New("not found")
type QueryError struct {
Query string
Err error
}
func (e *QueryError) Error() string {
return fmt.Sprintf("query %q: %v", e.Query, e.Err)
}
func (e *QueryError) Unwrap() error { return e.Err }
func main() {
err := &QueryError{"SELECT *", ErrNotFound}
fmt.Println(err)
fmt.Println(errors.Is(err, ErrNotFound)) // true
}errors.Is: comprobación de identidad
errors.Is recorre la cadena de errores en busca de un error igual al objetivo:
package main
import ("fmt"; "errors")
var ErrTimeout = errors.New("timeout")
func deepCall() error {
return fmt.Errorf("layer3: %w", fmt.Errorf("layer2: %w", ErrTimeout))
}
func main() {
err := deepCall()
fmt.Println(errors.Is(err, ErrTimeout)) // true — found deep in chain
}errors.As: extracción de tipos
errors.As busca en la cadena el primer error que coincide con un tipo objetivo y lo asigna:
package main
import ("fmt"; "errors")
type PermissionError struct{ User string }
func (e *PermissionError) Error() string { return "permission denied for " + e.User }
func action(user string) error {
return fmt.Errorf("action: %w", &PermissionError{user})
}
func main() {
err := action("bob")
var pe *PermissionError
if errors.As(err, &pe) {
fmt.Println("denied:", pe.User) // denied: bob
}
}Envoltorio de múltiples errores (Go 1.20+)
Go 1.20 añadió errors.Join y fmt.Errorf con varios %w para unir errores:
package main
import ("fmt"; "errors")
func validate(name, email string) error {
var errs []error
if name == "" { errs = append(errs, errors.New("name required")) }
if email == "" { errs = append(errs, errors.New("email required")) }
return errors.Join(errs...)
}
func main() {
err := validate("", "")
fmt.Println(err)
// name required
// email required
}Convenciones para nombrar tipos de error
Convenciones para las variables y los tipos de error en Go:
- Variables de error centinela:
ErrXxx(por ejemplo,ErrNotFound) - Tipos de error personalizados:
XxxError(por ejemplo,ValidationError) - Utilice una variable a nivel de paquete para errores centinela y un tipo puntero para errores con datos detallados
- Expórtelos para que los llamadores puedan utilizarlos con
errors.Is/errors.As
Cuándo utilizar cada enfoque
Cómo elegir el enfoque adecuado para los errores:
errors.New: sencillo, sin datos adicionales, para comprobar la identidad de errores centinelafmt.Errorf: mensaje formateado con envoltorio opcional- Tipo personalizado: cuando el llamador necesita datos estructurados (campos, códigos)
errors.Join: para agregar varios errores de validación
Comprobación rápida
¿Qué función permite extraer un tipo de error específico de una cadena de errores?
Repaso: errores personalizados
Resumen:
- Implemente
Error() stringpara crear tipos de error personalizados - Añada
Unwrap() errorpara participar en las cadenas de errores - Utilice
errors.Ispara comprobar identidades yerrors.Aspara extraer tipos - Errores centinela:
ErrXxx; tipos personalizados:XxxError errors.Joinagrega varios errores (Go 1.20+)
Preguntas frecuentes
¿La lección «Creación de errores personalizados» es gratis?
Sí — el texto completo de «Creación de errores personalizados» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Creación de errores personalizados»?
errors.New, fmt.Errorf y errores centinela Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Go Academy?
No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Creación de errores personalizados»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Go Academy?
Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- La interfaz error
- Creación de errores personalizados
- Envoltorio y desenvoltorio de errores
- panic, recover y defer