Salida de Color y Errores Amigables para el Usuario
Los operadores juzgan las CLIs por la claridad de sus errores: qué falló, qué arreglar a continuación y si la automatización puede detectar la clase de fallo.
Busca en todas las páginas de la documentación
Los operadores juzgan las CLIs por la claridad de sus errores: qué falló, qué arreglar a continuación y si la automatización puede detectar la clase de fallo.
Las herramientas de Go separan stdout (contrato de datos) de stderr (logs, advertencias, pistas coloreadas).
Bibliotecas como fatih/color y lipgloss añaden colores ANSI cuando la salida es una terminal y degradan elegantemente en los logs de CI.
Los errores amigables para el usuario comienzan con valores de error envueltos, terminan con mensajes concisos en stderr y finalizan con códigos de os.Exit documentados.
El color resalta la severidad (error rojo, advertencia amarilla, éxito verde) sin contaminar JSON o TSV en stdout.
Deshabilita el estilo cuando se establece NO_COLOR o cuando stdout/stderr no es una TTY.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
func fail(err error) {
color.New(color.FgRed).Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
func main() {
if err := run(); err != nil {
fail(err)
}
}Cuándo usar esto:
package main
import (
"errors"
"fmt"
"io"
"os"
"github.com/fatih/color"
)
var (
errConfig = errors.New("archivo de configuración no encontrado")
errAuth = errors.New("fallo de autenticación")
)
const (
exitGeneral = 1
exitConfig = 2
exitAuth = 3
)
func usage(w io.Writer) {
fmt.Fprintln(w, "uso: mytool --config path.yaml")
}
func run(args []string) error {
if len(args) == 0 {
usage(os.Stderr)
return errConfig
}
return nil
}
func main() {
color.NoColor = os.Getenv("NO_COLOR") != ""
err := run(os.Args[1:])
if err == nil {
color.New(color.FgGreen).Fprintln(os.Stderr, "ok")
return
}
switch {
case errors.Is(err, errConfig):
color.New(color.FgYellow).Fprintln(os.Stderr, "pista: copia config.example.yaml a config.yaml")
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(exitConfig)
case errors.Is(err, errAuth):
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(exitAuth)
default:
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(exitGeneral)
}
}Lo que esto demuestra:
errConfig, errAuth) se mapean a códigos de salida distintos.NO_COLOR deshabilita ANSI para accesibilidad y CI.fmt.Errorf("cargar %s: %w", path, err) envuelve errores para errors.Is y errors.As.main traduce los errores a códigos de salida una vez; las bibliotecas devuelven error sin os.Exit.| Flujo | Contenido | Ejemplos |
|---|---|---|
| stdout | Legible por máquina | Líneas JSON, IDs, tablas compatibles con kubectl |
| stderr | Orientado a humanos | Errores, advertencias, progreso, depuración |
| código de salida | Señal de automatización | 0 ok, 2 config, 3 auth |
| Código | Significado |
|---|---|
| 0 | Éxito |
| 1 | Fallo general |
| 2 | Error de uso o configuración |
| 3+ | Específico del dominio (documentar en README) |
// slog para modo verboso en stderr
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo}))color directamente en nombre de los llamadores; devuelven errores hacia arriba.SilenceErrors: true e imprime errores estilizados en main después de Execute.bytes.Buffer y color.NoColor = true para afirmaciones estables.tool | jq cuando ANSI se filtra en JSON. Solución: colorear solo stderr.flag.Usage y la ayuda de cobra apuntan a stderr.defer y previene el envoltorio. Solución: salir solo en main.NO_COLOR y TTY antes de estilizar.
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| fmt simple (sin color) | Herramientas solo para CI, logs archivados | La experiencia de terminal es un requisito del producto |
| lipgloss | Temas consistentes con bubbletea | Una línea de error roja es suficiente |
| plantillas de error de cobra | Ya se usa cobra | Herramientas simples de flag |
| solo log/slog | Modo de diagnóstico verboso | Los operadores necesitan correcciones para copiar y pegar |
Las marcas de verificación verdes opcionales en stderr ayudan a los humanos.
No imprimas prosa de éxito en stdout cuando el contrato sea JSON.
Usa %w e imprime err una vez en el nivel superior.
El modo verboso puede registrar fmt.Sprintf("%+v", err) con pkg/errors si se importa.
Una convención: cuando se establece, deshabilita el color ANSI.
Respétalo junto con la detección de TTY.
El Terminal de Windows moderno admite ANSI.
Las consolas antiguas pueden necesitar color.NoColor = true explícitamente; prueba los binarios de lanzamiento en los shells de destino.
Evita colorear JSON de stdout.
El formato bonito para humanos pertenece a un flag --format table o a un resumen en stderr.
Execute imprime los errores devueltos en stderr por defecto.
Establece SilenceErrors para aplicar estilo personalizado en main.
Sí para advertencias no fatales.
Usa salida 1+ solo cuando la operación falló o el éxito parcial es inaceptable.
Usa os/exec para ejecutar el binario compilado en las pruebas, o factoriza la lógica en run() error y prueba los errores sin salir.
Cuando los operadores necesitan marcas de tiempo y niveles en ejecuciones largas.
Combina slog para --verbose y mantén los errores predeterminados en una línea.
Las CLIs exponen correcciones inmediatas; los servicios registran los mismos errores envueltos con IDs de solicitud.
Comparte tipos de error centinela entre los paquetes cmd e internal.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado GC Green Tea, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica objetivos de placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 19 jul 2026