CodeGym /Cursos /SQL SELF /Log de erros: níveis de log e formatação de mensagens

Log de erros: níveis de log e formatação de mensagens

SQL SELF
Nível 55 , Lição 2
Disponível

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.

2
Tarefa
SQL SELF, nível 55, lição 2
Bloqueado
Log de erros na validação de dados
Log de erros na validação de dados
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION