CodeGym /Cursos /SQL SELF /Registro de errores: niveles de logging y formato de mens...

Registro de errores: niveles de logging y formato de mensajes

SQL SELF
Nivel 55 , Lección 2
Disponible

Ahora mismo somos como agentes secretos: nuestras funciones y procedimientos cumplen misiones, procesan datos, hacen cálculos o simplemente hacen magia dentro de la base. Pero, ¿cómo saber si algo sale mal? ¿Cómo entender en qué paso se rompió la "bañera de masaje para datos"? Aquí es donde entran en juego el logging y el manejo de errores.

Recuerda, ya empezamos a ver cómo en PostgreSQL y PL/pgSQL se puede "comunicar" y dejar logs:

  • RAISE NOTICE: tono tranquilo y amigable — "Ey, todo bien por aquí, pero igual te interesa echarle un ojo".
  • RAISE WARNING: tono un poco más alto — "Uy, aquí hay algo raro, quizá quieras mirar".
  • RAISE EXCEPTION: sirena de pánico — "¡STOP! ¡El algoritmo está en problemas! Paramos la ejecución para que no se vaya todo al garete".

Cada uno de estos niveles tiene su propósito, y es importante elegir bien cuál usar.

Así se ven estos mensajes en el código:

DO $$
BEGIN
    -- Nivel NOTICE (todo bien, solo aviso)
    RAISE NOTICE 'Solo aviso: empezó el procesamiento de datos';

    -- Nivel WARNING (algo sospechoso)
    RAISE WARNING 'Advertencia: el formato de los datos en la columna puede ser incorrecto';

    -- Nivel EXCEPTION (error crítico)
    RAISE EXCEPTION 'Error: ¡el valor de entrada no es válido!';
END $$;

Cuándo usar:

  • RAISE NOTICE — para debug y mostrar info tranquila.
  • RAISE WARNING — para avisar de datos potencialmente incorrectos.
  • RAISE EXCEPTION — cuando hay errores críticos que deben parar la función.

Manejo de errores con RAISE EXCEPTION

RAISE EXCEPTION es tu freno de emergencia. Si algo va mal, puedes parar la función y avisar del error.

Recuerda, el uso básico es así:

RAISE EXCEPTION 'Tu mensaje de error';

Pero para que los mensajes sean más informativos, puedes usar variables:

DECLARE
    input_value INTEGER;
BEGIN
    input_value := NULL;

    IF input_value IS NULL THEN
        RAISE EXCEPTION 'Error: el valor de entrada es NULL. Se esperaba un valor INTEGER';
    END IF;
END;

Formateo de mensajes

Puedes meter variables directamente en el texto del mensaje:

DECLARE
    var1 TEXT := 'Datos';
    var2 INTEGER := 42;
BEGIN
    RAISE EXCEPTION 'Error al procesar % con ID %', var1, var2;
END;

Salida: Error al procesar Datos con ID 42.

Ejemplo: validación de datos

Imagina que tienes un procedimiento que recibe la edad de una persona. Si la edad es negativa, tiene sentido lanzar un error:

CREATE OR REPLACE FUNCTION validate_age(age INTEGER)
RETURNS VOID AS $$
BEGIN
    IF age < 0 THEN
        RAISE EXCEPTION 'La edad no puede ser negativa: %', age;
    END IF;
END;
$$ LANGUAGE plpgsql;

-- Llamada a la función
SELECT validate_age(-5);  -- Lanza un error

Informar con RAISE NOTICE

Si RAISE EXCEPTION es la sirena, RAISE NOTICE es una palmada amistosa en el hombro. Con este nivel puedes meter comentarios para entender qué pasa dentro de la función.

Cuándo usar RAISE NOTICE:

  • Mostrar info de debug (por ejemplo, el estado actual de variables).
  • Mensaje de inicio de etapa o resultado de cálculos.

Ejemplo: mensajes informativos

CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount_rate NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    final_price NUMERIC;
BEGIN
    RAISE NOTICE 'Precio antes del descuento: %', price;
    RAISE NOTICE 'Tasa de descuento: %', discount_rate;

    final_price := price - (price * discount_rate);

    RAISE NOTICE 'Precio final: %', final_price;

    RETURN final_price;
END;
$$ LANGUAGE plpgsql;

-- Llamada a la función
SELECT calculate_discount(100, 0.2);
-- Muestra:
-- NOTICE: Precio antes del descuento: 100
-- NOTICE: Tasa de descuento: 0.2
-- NOTICE: Precio final: 80

Uso práctico: planificación y logging

Supón que tienes un procedimiento complicado de procesamiento de datos y quieres saber en qué paso está:

CREATE OR REPLACE FUNCTION process_data_step_by_step()
RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Paso 1: Preparación de datos';
    -- Tu lógica para la primera etapa

    RAISE NOTICE 'Paso 2: Validación de datos';
    -- Tu lógica para la segunda etapa

    RAISE NOTICE 'Paso 3: Guardado de datos';
    -- Tu lógica para la tercera etapa
END;
$$ LANGUAGE plpgsql;

-- Llamada a la función
SELECT process_data_step_by_step();
-- En los logs se verá la ejecución paso a paso

Otro ejemplo. Imagina una tienda que ofrece descuentos solo para pedidos por encima de cierta cantidad:

CREATE OR REPLACE FUNCTION apply_discount(order_amount NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    IF order_amount < 50 THEN
        RAISE EXCEPTION 'Error: el importe del pedido debe ser al menos 50, importe actual: %', order_amount;
    END IF;

    RETURN order_amount * 0.9;  -- Aplicamos 10% de descuento
END;
$$ LANGUAGE plpgsql;

-- Llamada a la función
SELECT apply_discount(30);  -- Error: el importe del pedido debe ser al menos 50

Errores típicos

Error 1: logging de mensajes sin parámetros.

Queda poco informativo, sobre todo en procedimientos grandes:

RAISE NOTICE 'Ocurrió un error';  -- ¿Por qué? ¿Dónde? ¿Cómo?

Recomendación: añade siempre contexto:

RAISE NOTICE 'Error en la función process_data(): valor de entrada: %', input_value;

Error 2: usar RAISE EXCEPTION donde basta con RAISE WARNING.

Si te pasas con las excepciones, el código se parará por cualquier cosa y será difícil procesar datos.

Consejo: usa los niveles de logging con cabeza. Para debug usa NOTICE, para cosas críticas — EXCEPTION.

Error 3: no hacer logging en absoluto.

Es como buscar las llaves en una habitación oscura. Sin logs, depurar procesos complejos es casi imposible.

Consejo: mete RAISE NOTICE en los pasos clave de la función, sobre todo si es grande y complicada.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION