Imagina a situação: você tá mexendo no banco de dados, processando um monte de transações, e aí alguma coisa dá ruim. O usuário reclama, o pessoal do negócio surta, e você nem sabe o que rolou de verdade. É aí que entra o log de erros do jeito certo. Ele serve pra:
- Guardar os erros no banco pra você analisar depois.
- Recuperar fácil os detalhes do erro: quando rolou, qual foi a mensagem e os dados relacionados.
- Melhorar seu código, corrigindo os erros mais comuns que aparecem nos logs.
Resumindo, logar é tipo ter uma câmera de segurança pro seu banco de dados: você vê tudo que deu ruim e quando aconteceu.
Criando a tabela error_log
Bora começar pelo básico. A gente precisa criar uma tabela pra guardar as infos dos erros. Ela vai ter esses campos:
id— identificador único do erro.error_message— texto do erro.error_time— quando o erro rolou.- (Opcional)
context— contexto do erro, caso precise guardar mais detalhes.
CREATE TABLE error_log (
id SERIAL PRIMARY KEY, -- Identificador único do erro
error_message TEXT NOT NULL, -- Mensagem de erro em texto
error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- Momento em que o erro rolou
context JSONB -- Dados extras sobre o erro
);
O que tá rolando aqui?
id SERIAL PRIMARY KEY— esse campo cria um identificador único pra cada registro automaticamente.error_message TEXT NOT NULL— aqui vai o texto do erro. É obrigatório preencher.error_time TIMESTAMP NOT NULL DEFAULT NOW()— campo que marca a hora do evento. Se você não passar nada, ele coloca a hora atual por causa doDEFAULT NOW().context JSONB— opcional, pra guardar info extra, tipo dados da operação onde o erro rolou.
Depois de rodar o CREATE TABLE, seu banco já vai ter a estrutura pra guardar os logs.
Exemplo de como gravar erros na tabela
Agora que a tabela tá pronta, bora pra prática: vamos salvar as infos dos erros nela. Vamos criar uma função que grava o texto do erro e o horário no error_log.
Exemplo de função pra gravar erros
CREATE OR REPLACE FUNCTION log_error(p_error_message TEXT, p_context JSONB DEFAULT NULL)
RETURNS VOID AS $$
BEGIN
INSERT INTO error_log (error_message, context)
VALUES (p_error_message, p_context);
END;
$$ LANGUAGE plpgsql;
p_error_message— parâmetro de entrada, recebe o texto do erro.p_context— parâmetro opcional pra passar dados extras. Por padrão éNULL.INSERT INTO error_log (error_message, context)— adiciona um novo registro na tabelaerror_log.DEFAULT NULL— se não passar contexto, o campo ficaNULL.
Agora, se quiser gravar uma mensagem de erro, é só chamar a função assim:
SELECT log_error('Erro ao executar a query', '{"query": "SELECT * FROM data"}');
Isso vai adicionar um novo registro na tabela error_log.
Log automático de erros
Ficar escrevendo SELECT log_error(...) toda hora é chato. Bora automatizar isso usando tratamento de exceções.
Exemplo de função com tratamento de exceção.
CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
result NUMERIC;
BEGIN
-- Vamos tentar dividir
result := a / b;
-- Retorna o resultado
RETURN result;
EXCEPTION
WHEN division_by_zero THEN
-- Loga o erro e passa o contexto
PERFORM log_error('Divisão por zero', jsonb_build_object('a', a, 'b', b));
-- Gera uma exceção pro usuário
RAISE EXCEPTION 'Não dá pra dividir % por % — o divisor é zero', a, b;
END;
$$ LANGUAGE plpgsql;
- Checando a divisão: faz
result := a / b. Seb = 0, o PostgreSQL lança a exceçãodivision_by_zero. - Tratador de exceção (
EXCEPTION) pega o erro. - No tratador, a gente chama a função
log_errorpra gravar o erro na tabela junto com os parâmetros que causaram o problema. - Depois de logar, com
RAISE EXCEPTIONa gente manda uma mensagem de erro pro usuário também.
Exemplo de chamada:
SELECT divide_numbers(10, 0);
Resultado:
- O usuário vai ver o erro:
Não dá pra dividir 10 por 0 — o divisor é zero. - Na tabela
error_logvai aparecer um registro sobre a divisão por zero.
GO TO FULL VERSION