Sentinel Errors & errors.Is
Erros sentinela são variáveis em nível de pacote que representam uma identidade de falha fixa.
Busque em todas as páginas da documentação
Erros sentinela são variáveis em nível de pacote que representam uma identidade de falha fixa.
Os chamadores os reconhecem com errors.Is em vez de correspondência de strings ou verificações == frágeis que falham assim que os erros são encapsulados.
Erros sentinela dão à sua API um pequeno vocabulário de resultados estáveis: não encontrado, já existe, cancelado, entrada inválida.
O Go 1.13 adicionou errors.Is para que essas identidades sobrevivam às cadeias de encapsulamento fmt.Errorf("...: %w", err).
Use sentinelas para contratos entre pacotes; opte por tipos customizados quando os chamadores precisarem de campos estruturados.
Cartão de receita de referência rápida - pronto para copiar e colar.
var ErrNotFound = errors.New("not found")
func Find(id string) (Item, error) {
if id == "" {
return Item{}, ErrNotFound
}
return Item{}, nil
}
if errors.Is(err, ErrNotFound) {
// lida com recurso ausente
}Quando usar isso:
io.EOF, os.ErrNotExist) se aplicam ao seu domíniopackage main
import (
"errors"
"fmt"
"os"
)
var ErrUserNotFound = errors.New("user not found")
func loadUser(path string) error {
_, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("load user %q: %w", path, ErrUserNotFound)
}
return fmt.Errorf("load user %q: %w", path, err)
}
return nil
}
func main() {
err := loadUser("alice.json")
switch {
case errors.Is(err, ErrUserNotFound):
fmt.Println("client: 404 user missing")
case err != nil:
fmt.Println("client: 500", err)
default:
fmt.Println("ok")
}
}O que isso demonstra:
ErrUserNotFound) é mapeado para um resultado do clientefmt.Errorf com %w preserva sentinelas os e de domínio na cadeiaerrors.Is encontra ErrUserNotFound através dos wrapsos.IsNotExist é um wrapper de conveniência em torno de errors.Is(err, os.ErrNotExist)errors.New retorna um valor de erro opaco com uma identidade fixa.%w implementa Unwrap() error, ligando erros externos e internos.errors.Is(err, target) retorna true se err == target ou qualquer etapa de unwrap corresponder.err == ErrX direto falha quando um wrapper está entre o chamador e o sentinela.| Padrão | Exemplo | Orientação |
|---|---|---|
| Sentinela exportado | var ErrNotFound = errors.New(...) | Parte do contrato público |
| Sentinela não exportado | var errStale = errors.New(...) | Apenas interno do pacote |
| Biblioteca padrão | io.EOF, context.Canceled | Use errors.Is, não strings.Contains |
io.EOF sinaliza o fim do stream durante Read, não necessariamente uma falha catastrófica.
Faça um loop até errors.Is(err, io.EOF) após processar o último chunk.
// Ruim: falha após o wrap
if err == ErrNotFound { ... }
// Bom
if errors.Is(err, ErrNotFound) { ... }
// Também bom para helpers da stdlib
if os.IsNotExist(err) { ... }== após encapsular - Erros encapsulados nunca são iguais ao sentinela. Correção: Use errors.Is.ErrX se tornam difíceis de documentar. Correção: Agrupe falhas relacionadas em um tipo customizado ou enum de código de erro.strings.Contains - Frágil através de wraps e mudanças de redação. Correção: errors.Is ou errors.As.return (*MyError)(nil) faz err != nil ser true. Correção: return nil ou var err error = nil.errors.Is(err, io.EOF) separadamente de erros reais.| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
Struct customizada + errors.As | Chamadores precisam de campos (nome do campo, retryable) | Apenas um branch sim/não é necessário |
| Códigos de erro em um tipo | Muitas variantes relacionadas compartilham a forma | Cada variante é verdadeiramente independente |
| Erros opacos | Ocultar implementação de chamadores | Chamadores precisam de errors.Is através da cadeia |
fmt.Errorf sem %w | A causa interna não deve ser inspecionável | Chamadores precisam de errors.Is através da cadeia |
Um valor var ErrX = errors.New("...") em nível de pacote com identidade estável. Chamadores o reconhecem com errors.Is.
O encapsulamento cria um novo valor de erro cujo alvo de comparação direto é o encapsulador, não o sentinela. errors.Is percorre Unwrap.
Exporte apenas erros que fazem parte da sua API documentada. Mantenha falhas internas não exportadas ou opacas.
Use o prefixo Err e PascalCase: ErrNotFound, ErrConflict. Siga o estilo da biblioteca padrão do Go.
Sim. errors.Is(err, io.EOF) é a verificação idiomática em loops de leitura e funciona através de wraps.
os.IsNotExist é um helper que verifica os.ErrNotExist (e wraps) em qualquer erro. errors.Is é o mecanismo geral.
Retorne sentinelas (ou erros tipados) para resultados de contrato; encapsule com contexto usando fmt.Errorf e %w em cada camada.
Se você precisar de uma tabela para explicá-los, considere um erro tipado com um campo de código ou tipos separados por categoria.
Sim. errors.Is verifica cada erro em um valor unido (Go 1.20+).
Quando o erro encapsulado não deve ser visível para Is/As, como ao sanitizar mensagens em um limite de API pública.
É um valor error usado para fluxo de controle no final da entrada. Trate-o explicitamente em vez de registrá-lo como uma falha.
Mapeie com errors.Is em handlers: not found para 404, conflict para 409. Mantenha o mapeamento no limite do transporte.
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão GC Green Tea, go fix modernizers - verifique o patch na compilação), chi (latest - verifique na compilação), gin (latest - verifique na compilação), echo (latest - verifique na compilação), google.golang.org/grpc (latest - verifique na compilação), sigs.k8s.io/controller-runtime (latest - verifique na compilação), kubebuilder (latest - verifique na compilação), tinygo (latest - verifique os alvos de placa na compilação), wazero (latest - verifique na compilação) e golangci-lint (latest - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026