Menu
Coddy logo textTech

Wrapping de Erros com `%w`

Parte da seção Lógica & Fluxo do Journey de GO da Coddy. Lição 39 de 68.

Quando ocorrem erros na sua aplicação, eles geralmente precisam de contexto adicional à medida que sobem pelas diferentes camadas do seu código. Go oferece um mecanismo avançado para isso por meio do encapsulamento de erros, usando o verbo de formatação %w com fmt.Errorf.

O encapsulamento de erros permite adicionar informações contextuais a um erro existente, preservando o erro original subjacente. Isso cria uma cadeia de erros que mantém o histórico completo do que deu errado:

originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)

O verbo %w é especial - ele diz ao fmt.Errorf para envolver o erro em vez de apenas convertê-lo em uma string. Isso preserva o erro original para que ele possa ser examinado mais tarde usando funções como errors.Is e errors.As.

Este padrão é particularmente valioso em aplicações maiores, nas quais um erro pode passar por várias funções, cada uma adicionando seu próprio contexto. Por exemplo, um erro de conexão com o banco de dados pode ser envolvido com "failed to connect to database" e, em seguida, envolvido novamente com "unable to start server", criando um caminho claro do que aconteceu e onde.

challenge icon

Desafio

Fácil

Crie um sistema de processamento de arquivos que envolva erros com informações contextuais à medida que eles se propagam por diferentes camadas da sua aplicação. Este desafio demonstra como usar o verbo de formatação %w com fmt.Errorf para criar cadeias de erros que preservam o erro original enquanto adicionam um contexto significativo.

Você receberá duas entradas:

  • Uma string contendo detalhes da operação de arquivo no formato "filename,operation,status" (por exemplo, "config.json,read,permission_denied")
  • Uma string contendo o contexto do sistema no formato "service_name,component" (por exemplo, "UserService,ConfigLoader")

Sua tarefa é:

  1. Analisar a primeira entrada dividindo-a pelas vírgulas para obter o nome do arquivo, a operação e o status
  2. Analisar a segunda entrada dividindo-a pelas vírgulas para obter o nome do serviço e o componente
  3. Criar um erro original com base no status usando errors.New():
    • Se o status for "permission_denied": "permission denied"
    • Se o status for "not_found": "file not found"
    • Se o status for "corrupted": "file corrupted"
    • Para qualquer outro status: "unknown error"
  4. Criar um erro encapsulado no nível do arquivo usando fmt.Errorf com %w: "failed to [operation] file [filename]: %w"
  5. Criar um erro encapsulado no nível do componente: "[component] error: %w"
  6. Criar um erro encapsulado no nível do serviço: "[service_name] operation failed: %w"
  7. Exibir a cadeia de erros imprimindo cada nível:
    • "Original error: [original_error_message]"
    • "File level: [file_level_error_message]"
    • "Component level: [component_level_error_message]"
    • "Service level: [service_level_error_message]"
  8. Exibir um resumo da cadeia de erros:
    • "Error Chain Summary:"
    • "File: [filename]"
    • "Operation: [operation]"
    • "Component: [component]"
    • "Service: [service_name]"
    • "Root cause: [original_error_message]"

Use o pacote strings para dividir as strings de entrada pelas vírgulas, o pacote errors para criar o erro original e o pacote fmt para criar erros encapsulados. Este desafio demonstra como o encapsulamento de erros com %w cria um caminho claro de contexto à medida que os erros passam por diferentes camadas da sua aplicação, tornando a depuração muito mais eficaz.

Experimente você mesmo

package main

import (
	"errors"
	"fmt"
	"strings"
)

func main() {
	// Ler entrada
	var fileDetails string
	var systemContext string
	fmt.Scanln(&fileDetails)
	fmt.Scanln(&systemContext)
	
	// Analisar entradas
	fileInfo := strings.Split(fileDetails, ",")
	filename := fileInfo[0]
	operation := fileInfo[1]
	status := fileInfo[2]
	
	contextInfo := strings.Split(systemContext, ",")
	serviceName := contextInfo[0]
	component := contextInfo[1]
	
	// TODO: Escreva seu código abaixo
	// Criar erro original baseado no status
	// Criar erro encapsulado no nível de arquivo
	// Criar erro encapsulado no nível de componente
	// Criar erro encapsulado no nível de serviço
	// Imprimir cada nível de erro e o resumo
	
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica & Fluxo

Pratique por conta própria: Compilador de Go online