35/100 Dias de Golang - Error Handling
Table of Contents
#
Error Handling
O tratamento de erros em Go é bem diferente do que em outras linguagem, não temos o tradicional try/except
. Os erros em Go são simplesmente retornados como uma variável normal, daí que surge o famoso if err != nil {}
do Golang. Nas primeiras vezes que vi essa estrutura foi meio estranho, mas depois fez bastante sentido. Essa estrutura vai completamente de encontro ao design da linguagem do Golang, manter a simplicidade e eficiencia da linguagem. Vamos criar uma função de divisão e retornar um erro quando o divisor é 0.
func Divisao(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("Não posso dividr '%d' por zero", a)
}
return a / b, nil
}
func main() {
resultado, err := Divisao(1, 0)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(resultado)
}
}
Podemos criar um erro personalizado:
var ErroDividePorZero = errors.New("Não posso dividr por zero")
func Divisao(a, b int) (int, error) {
if b == 0 {
return 0, ErroDividePorZero
}
return a / b, nil
}
func main() {
resultado, err := Divisao(1, 0)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(resultado)
}
}
#
Panic e Recover
A linguagem também oferece as funções panic
e recover
para situações realmente excepcionais, como bugs inesperados ou falhas graves. A função panic
interrompe a execução normal do programa e o recover
pode ser usado dentro de uma função defer
para capturar um panic
e evitar que o programa termine abruptamente.
func podeEntrarEmPanico() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recuperado do pânico:", r)
}
}()
panic("Algo muito errado aconteceu!")
}
func main() {
podeEntrarEmPanico()
}
#
Exemplo de Propagação e Tratamento de Erros
A função responsável por tratar o erro é aquela que tem contexto suficiente para tomar uma decisão adequada. Por exemplo, se uma função de leitura de arquivo falha, ela deve apenas retornar o erro. Já a função que chamou essa leitura pode decidir se tenta novamente, mostra uma mensagem para o usuário, ou encerra o programa.
func lerArquivo(nome string) ([]byte, error) {
dados, err := os.ReadFile(nome)
if err != nil {
return nil, err
}
return dados, nil
}
func processarArquivo(nome string) error {
dados, err := lerArquivo(nome)
if err != nil {
return fmt.Errorf("falha ao processar arquivo %s: %w", nome, err)
}
// Processa os dados...
return nil
}
func main() {
err := processarArquivo("dados.txt")
if err != nil {
log.Fatalf("Erro fatal: %w", err) // Tratamento final do erro
}
}
Veja a saída:
2025/04/16 14:18:10 Erro fatal: falha ao processar arquivo dados.txt: open dados.txt: no such file or directory
Veja que vamos propagando o erro e adicionando contexto a mensagem, na função processarArquivo
, retornamos return fmt.Errorf("falha ao processar arquivo %s: %w", nome, err)
. Tratamento de erros é um assunto bem complexo que podemos falar mais em outros posts, essa foi só uma introdução. Segue algumas referências: