Saída Colorida e Erros Amigáveis ao Usuário
Operadores julgam CLIs pela clareza dos erros: o que falhou, o que corrigir a seguir e se a automação pode detectar a classe da falha.
Busque em todas as páginas da documentação
Operadores julgam CLIs pela clareza dos erros: o que falhou, o que corrigir a seguir e se a automação pode detectar a classe da falha.
Ferramentas Go separam stdout (contrato de dados) de stderr (logs, avisos, dicas coloridas).
Bibliotecas como fatih/color e lipgloss adicionam cores ANSI quando a saída é um terminal e degradam graciosamente em logs de CI.
Erros amigáveis ao usuário começam com valores de error encapsulados, terminam com mensagens concisas de stderr e finalizam com códigos de os.Exit documentados.
A cor destaca a gravidade (vermelho para erro, amarelo para aviso, verde para sucesso) sem poluir JSON ou TSV no stdout.
Desabilita a estilização quando NO_COLOR é definido ou quando stdout/stderr não é um TTY.
Cartão de receita de referência rápida - pronto para copiar e colar.
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)
}
}Quando usar isso:
package main
import (
"errors"
"fmt"
"io"
"os"
"github.com/fatih/color"
)
var (
errConfig = errors.New("arquivo de configuração não encontrado")
errAuth = errors.New("falha na autenticação")
)
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, "dica: copie config.example.yaml para config.yaml")
fmt.Fprintln(os.Stderr, "erro:", err)
os.Exit(exitConfig)
case errors.Is(err, errAuth):
fmt.Fprintln(os.Stderr, "erro:", err)
os.Exit(exitAuth)
default:
fmt.Fprintln(os.Stderr, "erro:", err)
os.Exit(exitGeneral)
}
}O que isso demonstra:
errConfig, errAuth) mapeiam para códigos de saída distintos.NO_COLOR desabilita ANSI para acessibilidade e CI.fmt.Errorf("load %s: %w", path, err) encapsula erros para errors.Is e errors.As.main traduz erros para códigos de saída uma vez; bibliotecas retornam error sem os.Exit.| Stream | Conteúdo | Exemplos |
|---|---|---|
| stdout | Legível por máquina | Linhas JSON, IDs, tabelas compatíveis com kubectl |
| stderr | Orientado a humanos | erros, avisos, progresso, depuração |
| código de saída | Sinal de automação | 0 ok, 2 config, 3 auth |
| Código | Significado |
|---|---|
| 0 | Sucesso |
| 1 | Falha geral |
| 2 | Erro de uso ou configuração |
| 3+ | Específico do domínio (documentar no README) |
// slog para modo verboso no stderr
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo}))color diretamente em nome de chamadores; retorne erros para cima.SilenceErrors: true e imprima erros estilizados em main após Execute.bytes.Buffer e color.NoColor = true para asserções estáveis.tool | jq quando ANSI vaza para JSON. Correção: colore apenas stderr.flag.Usage e a ajuda do cobra direcionam para stderr.main.NO_COLOR e TTY antes de estilizar.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| fmt simples (sem cor) | Ferramentas apenas para CI, logs arquivados | UX do terminal é um requisito do produto |
| lipgloss | Temas consistentes com bubbletea | Uma linha de erro vermelha é suficiente |
| modelos de erro cobra | Já usando cobra | Ferramentas simples com flag |
| apenas log/slog | Modo de diagnóstico verboso | Operadores precisam de correções copiáveis |
Marcos verdes opcionais no stderr ajudam os humanos.
Não imprima prosa de sucesso no stdout quando o contrato for JSON.
Use %w e imprima err uma vez no nível superior.
O modo verboso pode registrar fmt.Sprintf("%+v", err) com pkg/errors se importado.
Uma convenção: quando definido, desabilita a cor ANSI.
Honre-o ao lado da detecção de TTY.
O Windows Terminal moderno suporta ANSI.
O conhost mais antigo pode precisar de color.NoColor = true explícito; teste binários de lançamento nos shells de destino.
Evite colorir JSON stdout.
A impressão formatada para humanos pertence a um sinalizador --format table ou a um resumo de stderr.
Execute imprime erros retornados no stderr por padrão.
Defina SilenceErrors para aplicar estilização personalizada em main.
Sim para avisos não fatais.
Use saída 1+ apenas quando a operação falhou ou o sucesso parcial for inaceitável.
Use os/exec para executar o binário compilado em testes, ou fatore a lógica em run() error e teste erros sem sair.
Quando operadores precisam de timestamps e níveis em execuções longas.
Combine slog para --verbose e mantenha os erros padrão em uma linha.
CLIs apresentam correções imediatas; serviços registram os mesmos erros encapsulados com IDs de solicitação.
Compartilhe tipos de erro sentinela entre pacotes cmd e internal.
Versões de Stack: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, go fix modernizers - verifique o patch na compilação), chi (última - verifique na compilação), gin (última - verifique na compilação), echo (última - verifique na compilação), google.golang.org/grpc (última - verifique na compilação), sigs.k8s.io/controller-runtime (última - verifique na compilação), kubebuilder (última - verifique na compilação), tinygo (última - verifique os alvos de placa na compilação), wazero (última - verifique na compilação) e golangci-lint (última - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026