CodeGym /Cursos /SQL SELF /Manejo de errores: RAISE EXCEPTION

Manejo de errores: RAISE EXCEPTION

SQL SELF
Nivel 52 , Lección 0
Disponible

Imagínate que estás escribiendo una función que calcula la nota media de un estudiante. ¿Qué pasa si intentas dividir por cero (por ejemplo, si no hay notas)? Si intentas lanzar ese código a producción, el error va a aparecer de inmediato. PL/pgSQL te da herramientas potentes para manejar estos errores, haciendo tu código más robusto, seguro y cómodo de trabajar.

El manejo de errores en PL/pgSQL te permite:

  1. Generar mensajes que expliquen qué salió mal.
  2. Parar la ejecución del código en caso de errores críticos.
  3. Registrar problemas para analizarlos después.

Niveles principales de mensajes en PL/pgSQL

PL/pgSQL soporta varios niveles de mensajes que ayudan a los desarrolladores a diagnosticar y solucionar problemas de forma eficiente. Aquí van:

  • NOTICE: muestra un mensaje informativo. Se usa para depuración.
  • WARNING: aviso sobre un posible problema que no interrumpe el programa.
  • EXCEPTION: error crítico que interrumpe la ejecución del programa (y devuelve el control al código que llamó).

Niveles de mensajes en PL/pgSQL

Nivel de mensaje Descripción
NOTICE Información o mensajes de depuración. No afecta la ejecución
WARNING Aviso sobre posibles problemas. Funciona como sugerencia
EXCEPTION Error serio que termina la ejecución del programa

Sintaxis del comando RAISE

Para generar mensajes y manejar errores se usa la sentencia RAISE. Aquí tienes la sintaxis básica:

RAISE <nivel de mensaje> 'texto del mensaje' [, variables...];
  • <nivel de mensaje>NOTICE, WARNING, EXCEPTION.
  • 'texto del mensaje' — descripción del problema.
  • [variables...] — valores adicionales que puedes meter en el texto del mensaje.

Ejemplo 1: usando RAISE NOTICE

A veces es importante saber qué pasa dentro de tu función. Por ejemplo, para depurar un bucle:

DO $$
BEGIN
    FOR i IN 1..5 LOOP
        RAISE NOTICE 'Valor actual de i: %', i;
    END LOOP;
END
$$;

Resultado: Se muestran en consola las líneas Valor actual de i: 1, Valor actual de i: 2 y así hasta 5.

Ejemplo 2: usando RAISE EXCEPTION

Ahora imagina que escribes una función que debe terminar con error bajo ciertas condiciones:

DO $$
BEGIN
    IF 1 = 1 THEN
        RAISE EXCEPTION '¡Algo salió mal!';
    END IF;
END
$$;

Resultado: la ejecución se interrumpe y el mensaje de error aparece en consola.

Trabajando con parámetros en RAISE

Usando parámetros puedes personalizar el texto del mensaje. Para eso se usan los placeholders %:

Ejemplo 3: insertar variables en RAISE

DO $$
DECLARE
    student_name TEXT := 'Iván';
    average_score NUMERIC := NULL;
BEGIN
    IF average_score IS NULL THEN
        RAISE EXCEPTION '¡El estudiante % no tiene nota media!', student_name;
    END IF;
END
$$;

Resultado: mensaje ¡El estudiante Iván no tiene nota media!.

Como ves, % se reemplaza por la variable student_name, haciendo el mensaje más claro.

Generando errores personalizados

¡Los errores no son solo mala suerte! A veces hay que crearlos a propósito para proteger el código de datos incorrectos.

Ejemplo 4: comprobando valores de entrada

Vamos a escribir una función que comprueba el valor de entrada y lanza un error si es negativo:

CREATE OR REPLACE FUNCTION check_positive(value NUMERIC)
RETURNS TEXT AS $$
BEGIN
    IF value < 0 THEN
        RAISE EXCEPTION '¡El número % es negativo!', value;
    END IF;
    RETURN 'El número es correcto.';
END;
$$ LANGUAGE plpgsql;

Ahora probamos la función:

SELECT check_positive(-5);

Resultado: mensaje de error ¡El número -5 es negativo!.

Si pasas un valor positivo:

SELECT check_positive(10);

Resultado: El número es correcto.

Manejo de errores en contexto

Está bien saber cómo lanzar errores. Pero aún mejor es manejarlos según la situación. Para eso se usa el bloque BEGIN ... EXCEPTION.

Estructura del manejo de errores

BEGIN
    -- Tu código principal
EXCEPTION
    WHEN TIPO_DE_ERROR THEN
        -- Qué hacer en caso de ese error
    WHEN OTRO_ERROR THEN
        -- Qué hacer con otro error
    WHEN OTHERS THEN
        -- Manejo de todos los demás errores
END;

Vamos a descifrar los componentes:

  • EXCEPTION — palabra clave que marca el inicio del bloque de manejo de errores.
  • WHEN — te deja indicar el tipo concreto de error a manejar, por ejemplo, unique_violation o division_by_zero.
  • OTHERS — se usa para manejar todos los errores que no se han especificado en los bloques WHEN.

Ejemplo 5: manejo de división por cero

Vamos a ilustrar el manejo de errores con un ejemplo sencillo de función de división:

CREATE OR REPLACE FUNCTION safe_divide(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    -- Intentamos hacer la división
    RETURN a / b;
EXCEPTION
    WHEN division_by_zero THEN
        RAISE WARNING 'Intento de división por cero. Devuelvo NULL.';
        RETURN NULL;
END;
$$ LANGUAGE plpgsql;

Probamos la función:

SELECT safe_divide(10, 2);  -- Resultado esperado: 5
SELECT safe_divide(10, 0);  -- Resultado esperado: NULL y aviso en consola

Errores típicos al usar RAISE

Olvidar el nivel de mensaje. Si te olvidas de poner el nivel, PostgreSQL te va a dar un error.

Incorrecto:

RAISE 'Mensaje sin nivel';

Correcto:

RAISE NOTICE 'Mensaje con nivel NOTICE';

Parámetros incorrectos. Si usas %, asegúrate de pasar el número correcto de variables.

Incorrecto:

RAISE NOTICE 'Ejemplo con parámetro %';

Correcto:

RAISE NOTICE 'Ejemplo con parámetro %', 'valor';

Abusar del RAISE. Usar demasiado RAISE EXCEPTION puede interrumpir operaciones importantes. Úsalo con cabeza.

Consejos útiles

  1. Ojo con el bloque WHEN OTHERS. Siempre que puedas, especifica errores concretos para no atrapar errores que deberían manejarse de otra forma.
  2. Usa RAISE para depurar. Nunca dejes errores sin manejar.
  3. No te olvides del rendimiento. El manejo de errores puede ser costoso, sobre todo en procedimientos grandes.

Si haces todo bien, tus procedimientos serán robustos y podrán aguantar hasta los fallos más inesperados. ¡Tu PM va a estar muy orgulloso de ti!

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