Médio Go
Envolvendo erros com %w e errors.Is
Enunciado
Crie uma função LerConfig(nome string) (string, error) que simula a leitura de um arquivo de configuração. Se nome for vazio, retorne um erro sentinela ErrNomeVazio. Se nome for "invalido", retorne um erro personalizado ErrConfigInvalida (também sentinela). Caso contrário, retorne "conteúdo de " + nome. No main, chame a função com "invalido" e use errors.Is para verificar se o erro é ErrConfigInvalida, imprimindo uma mensagem. Envolva o erro com contexto usando fmt.Errorf com %w.
Requisitos
- Definir dois erros sentinela:
ErrNomeVazioeErrConfigInvalida. - A função
LerConfigretornaErrNomeVaziosenome == "". - A função
LerConfigretornaErrConfigInvalidasenome == "invalido", envolto com%we contexto. - No
main, usarerrors.Ispara detectarErrConfigInvalidae imprimir"Configuração inválida detectada". - Imprimir também a mensagem completa do erro.
Código inicial
package main
import (
"errors"
"fmt"
)
var (
ErrNomeVazio = errors.New("nome vazio")
ErrConfigInvalida = errors.New("configuração inválida")
)
func LerConfig(nome string) (string, error) {
// Implemente
return "", nil
}
func main() {
// Chame LerConfig("invalido") e trate o erro
}
Saída esperada
Configuração inválida detectada
Erro completo: falha ao ler config: configuração inválida
Ver dica
Use fmt.Errorf("falha ao ler config: %w", ErrConfigInvalida) para envolver. No main, errors.Is encontrará o sentinela mesmo com o contexto extra.
Mostrar solução
package main
import (
"errors"
"fmt"
)
var (
ErrNomeVazio = errors.New("nome vazio")
ErrConfigInvalida = errors.New("configuração inválida")
)
// LerConfig simula a leitura de uma configuração.
func LerConfig(nome string) (string, error) {
if nome == "" {
return "", ErrNomeVazio
}
if nome == "invalido" {
// Envolve o erro sentinela com contexto usando %w
return "", fmt.Errorf("falha ao ler config: %w", ErrConfigInvalida)
}
return "conteúdo de " + nome, nil
}
func main() {
_, err := LerConfig("invalido")
if err != nil {
if errors.Is(err, ErrConfigInvalida) {
fmt.Println("Configuração inválida detectada")
}
fmt.Printf("Erro completo: %v\n", err)
}
}
Passo a passo
- Definimos dois erros sentinela:
ErrNomeVazioeErrConfigInvalida. - Em
LerConfig, senomefor vazio, retornamosErrNomeVaziodiretamente. - Se
nomefor"invalido", usamosfmt.Errorfcom%wpara envolverErrConfigInvalidae adicionar contexto ("falha ao ler config: "). - No
main, chamamosLerConfig("invalido")e obtemos o erro envolto. - Usamos
errors.Is(err, ErrConfigInvalida)para verificar se o erro original está na cadeia; como está, imprimimos a mensagem. - Imprimimos o erro completo com
%v, que mostra a mensagem contextualizada.
Por que funciona
%w faz com que o erro retornado por fmt.Errorf implemente o método Unwrap() error, permitindo que errors.Is percorra a cadeia até encontrar ErrConfigInvalida. Assim, mantemos o contexto sem perder a identidade do erro original.
Erros comuns
- Usar
%vem vez de%w:fmt.Errorf("falha: %v", ErrConfigInvalida)cria um novo erro sem envolver;errors.Isnão encontrará o sentinela. - Comparar diretamente com
==:if err == ErrConfigInvalidafalha porque o erro foi envolto. - Esquecer de importar
errors: erro de compilação.
Outra forma de resolver
Se não precisar de contexto, pode retornar o sentinela diretamente. Mas o envolvimento é útil para rastrear a origem.
Saída esperada
Configuração inválida detectada
Erro completo: falha ao ler config: configuração inválida