A gente agora tá tipo agente secreto — nossas funções e procedures fazem missões: processam dados, fazem contas ou simplesmente fazem mágica dentro do banco. Mas como saber se algo deu ruim? Como descobrir em que etapa quebrou a "banheira de hidromassagem dos dados"? É aí que entram o log e o tratamento de erros.
Lembra que a gente já começou a ver como no PostgreSQL e PL/pgSQL dá pra "conversar" e fazer logs:
RAISE NOTICE: tom de boa, amigável — "Ei, tá tudo certo aqui, mas talvez você queira dar uma olhada".RAISE WARNING: tom um pouco mais alto — "Opa, tem algo estranho aqui, talvez confere aí".RAISE EXCEPTION: sirene de pânico — "PARA! O algoritmo tá em apuros! Paramos tudo pra não dar ruim geral".
Cada um desses níveis tem seu propósito, e é importante escolher o certo pra cada situação.
Olha como essas mensagens ficam no código:
DO $$
BEGIN
-- Nível NOTICE (tá tudo bem, só avisando)
RAISE NOTICE 'Só um aviso: começou o processamento dos dados';
-- Nível WARNING (algo suspeito rolando)
RAISE WARNING 'Aviso: o formato dos dados na coluna pode estar errado';
-- Nível EXCEPTION (erro crítico)
RAISE EXCEPTION 'Erro: valor de entrada inválido!';
END $$;
Quando usar:
RAISE NOTICE— pra debug e mostrar info de boa.RAISE WARNING— pra avisar sobre dados que podem estar errados.RAISE EXCEPTION— quando rola erro crítico e a função tem que parar na hora.
Tratamento de erros com RAISE EXCEPTION
RAISE EXCEPTION é tipo o botão de emergência. Se algo der ruim, você consegue parar a função e avisar do erro.
Lembrando, o uso básico é assim:
RAISE EXCEPTION 'Sua mensagem de erro';
Mas pra deixar as mensagens mais informativas, dá pra usar variáveis:
DECLARE
input_value INTEGER;
BEGIN
input_value := NULL;
IF input_value IS NULL THEN
RAISE EXCEPTION 'Erro: valor de entrada NULL. Esperado valor INTEGER';
END IF;
END;
Formatando mensagens
Você pode colocar variáveis direto no texto da mensagem:
DECLARE
var1 TEXT := 'Dados';
var2 INTEGER := 42;
BEGIN
RAISE EXCEPTION 'Erro ao processar % com ID %', var1, var2;
END;
Saída: Erro ao processar Dados com ID 42.
Exemplo: validação de dados
Imagina que você tem uma procedure que recebe a idade de uma pessoa. Se a idade for negativa, faz sentido lançar um erro:
CREATE OR REPLACE FUNCTION validate_age(age INTEGER)
RETURNS VOID AS $$
BEGIN
IF age < 0 THEN
RAISE EXCEPTION 'Idade não pode ser negativa: %', age;
END IF;
END;
$$ LANGUAGE plpgsql;
-- Chamando a função
SELECT validate_age(-5); -- Vai lançar erro
Informando com RAISE NOTICE
Se RAISE EXCEPTION é a sirene, RAISE NOTICE é aquele tapinha amigável no ombro. Com esse nível, dá pra colocar comentários pra entender o que tá rolando dentro da função.
Quando usar RAISE NOTICE:
- Mostrar info de debug (tipo, o valor atual das variáveis).
- Avisar que começou uma etapa ou mostrar o resultado de algum cálculo.
Exemplo: mensagens informativas
CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount_rate NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
final_price NUMERIC;
BEGIN
RAISE NOTICE 'Preço antes do desconto: %', price;
RAISE NOTICE 'Taxa de desconto: %', discount_rate;
final_price := price - (price * discount_rate);
RAISE NOTICE 'Preço final: %', final_price;
RETURN final_price;
END;
$$ LANGUAGE plpgsql;
-- Chamando a função
SELECT calculate_discount(100, 0.2);
-- Vai mostrar:
-- NOTICE: Preço antes do desconto: 100
-- NOTICE: Taxa de desconto: 0.2
-- NOTICE: Preço final: 80
Aplicação prática: planejamento e log
Imagina que você tem uma procedure cabulosa de processamento de dados, e quer saber em que etapa ela tá agora:
CREATE OR REPLACE FUNCTION process_data_step_by_step()
RETURNS VOID AS $$
BEGIN
RAISE NOTICE 'Etapa 1: Preparando os dados';
-- Sua lógica pra primeira etapa
RAISE NOTICE 'Etapa 2: Validando os dados';
-- Sua lógica pra segunda etapa
RAISE NOTICE 'Etapa 3: Salvando os dados';
-- Sua lógica pra terceira etapa
END;
$$ LANGUAGE plpgsql;
-- Chamando a função
SELECT process_data_step_by_step();
-- No log vai aparecer o passo a passo
Mais um exemplo. Imagina uma loja que só dá desconto pra pedidos acima de um certo valor:
CREATE OR REPLACE FUNCTION apply_discount(order_amount NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
IF order_amount < 50 THEN
RAISE EXCEPTION 'Erro: valor do pedido deve ser pelo menos 50, valor atual: %', order_amount;
END IF;
RETURN order_amount * 0.9; -- Aplica 10% de desconto
END;
$$ LANGUAGE plpgsql;
-- Chamando a função
SELECT apply_discount(30); -- Erro: valor do pedido deve ser pelo menos 50
Erros comuns
Erro 1: logar mensagens sem parâmetros.
Fica sem graça, principalmente em procedures grandes:
RAISE NOTICE 'Ocorreu um erro'; -- Por quê? Onde? Como?
Recomendação: sempre coloca contexto:
RAISE NOTICE 'Erro na função process_data(): valor de entrada: %', input_value;
Erro 2: usar RAISE EXCEPTION onde RAISE WARNING já resolve.
Se exagerar nos exceptions, o código vai parar por qualquer coisa, e aí fica difícil processar os dados.
Dica: usa os níveis de log com consciência. Pra debug, vai de NOTICE, e pra coisa séria — EXCEPTION.
Erro 3: não logar nada.
É tipo procurar a chave no quarto escuro. Sem log, debugar processos grandes é quase impossível.
Dica: coloca RAISE NOTICE nos pontos chave da função, principalmente se ela for grande e cheia de coisa.
GO TO FULL VERSION