@errorName em Zig
O @errorName retorna o nome de um valor de erro como uma string legível. É uma ferramenta essencial para depuração, logging e mensagens de erro amigáveis. Em Zig, erros são valores de primeira classe, e este builtin permite converter esses valores para suas representações textuais.
Sintaxe
@errorName(err: anyerror) [:0]const u8
O que faz
O @errorName recebe um valor de erro e retorna seu nome como uma string de bytes constante terminada em sentinela nulo. O nome retornado corresponde exatamente ao identificador usado na declaração do error set.
Parâmetros
- err (
anyerror): Um valor de erro de qualquer error set. Deve ser um erro concreto, não um error union (!T).
Valor de retorno
Retorna [:0]const u8 — uma string terminada em zero contendo o nome do erro.
Exemplos práticos
Exemplo 1: Logging de erros
const std = @import("std");
const ArquivoErro = error{
NaoEncontrado,
PermissaoNegada,
DiskCheio,
Corrompido,
};
fn abrirArquivo(caminho: []const u8) ArquivoErro!void {
_ = caminho;
return ArquivoErro.NaoEncontrado;
}
test "logging de erros" {
const resultado = abrirArquivo("/tmp/teste.txt");
if (resultado) |_| {
// Sucesso
} else |err| {
const nome = @errorName(err);
std.debug.print("Erro ao abrir arquivo: {s}\n", .{nome});
// Saída: "Erro ao abrir arquivo: NaoEncontrado"
try std.testing.expectEqualStrings("NaoEncontrado", nome);
}
}
Exemplo 2: Sistema de logging estruturado
const std = @import("std");
const NivelLog = enum { debug, info, warn, err };
fn log(nivel: NivelLog, mensagem: []const u8, erro_opt: ?anyerror) void {
const prefixo = switch (nivel) {
.debug => "[DEBUG]",
.info => "[INFO]",
.warn => "[WARN]",
.err => "[ERRO]",
};
if (erro_opt) |err| {
std.debug.print("{s} {s} (erro: {s})\n", .{
prefixo,
mensagem,
@errorName(err),
});
} else {
std.debug.print("{s} {s}\n", .{ prefixo, mensagem });
}
}
test "logging estruturado" {
log(.info, "Servidor iniciado", null);
log(.err, "Falha na conexão", error.ConnectionRefused);
log(.warn, "Tentativa de acesso negada", error.PermissaoNegada);
}
Exemplo 3: Tradução de erros para mensagens amigáveis
const std = @import("std");
const DbErro = error{
ConexaoPerdida,
TabelaNaoExiste,
ChaveDuplicada,
TimeoutConsulta,
};
fn mensagemAmigavel(err: DbErro) []const u8 {
return switch (err) {
error.ConexaoPerdida => "A conexão com o banco de dados foi perdida. Tente novamente.",
error.TabelaNaoExiste => "A tabela solicitada não foi encontrada no banco de dados.",
error.ChaveDuplicada => "Já existe um registro com essa chave. Use um valor diferente.",
error.TimeoutConsulta => "A consulta demorou demais. Tente uma consulta mais simples.",
};
}
fn tratarErroDb(err: DbErro) void {
// Mensagem técnica para logs
std.debug.print("DB Error: {s}\n", .{@errorName(err)});
// Mensagem amigável para o usuário
std.debug.print("Mensagem: {s}\n", .{mensagemAmigavel(err)});
}
test "mensagens de erro" {
tratarErroDb(error.ConexaoPerdida);
tratarErroDb(error.ChaveDuplicada);
}
Casos de uso comuns
- Logging e monitoramento: Registrar o nome do erro em logs para diagnóstico e análise de incidentes.
- Mensagens de erro para o usuário: Exibir o nome técnico do erro junto com uma mensagem amigável.
- Serialização de erros: Converter erros para strings ao transmitir via rede (APIs, RPC).
- Depuração: Imprimir erros durante o desenvolvimento para entender fluxos de execução.
- Telemetria: Enviar nomes de erros para sistemas de monitoramento e alertas.
Observações
- O
@errorNamefunciona com qualquer error set, incluindoanyerror. - A string retornada é estática e válida durante toda a execução do programa.
- Não há operação inversa direta (string para erro) disponível como builtin. Para isso, seria necessário implementar manualmente usando
@typeInfo.
Builtins relacionados
- @tagName — Obtém o nome do campo ativo de uma tagged union
- @typeName — Obtém o nome de um tipo como string
- @typeInfo — Inspeciona error sets e outros tipos
- @compileError — Gera erro de compilação personalizado