JavaRush /Курсы /SQL SELF /Логирование ошибок: уровни логирования и формат сообщений...

Логирование ошибок: уровни логирования и формат сообщений

SQL SELF
55 уровень , 2 лекция
Открыта

Мы с вами сейчас как тайные агенты — наши функции и процедуры выполняют миссии: обрабатывают данные, выполняют вычисления или просто делают магию внутри базы. Но как узнать, если что-то пойдет не так? Как понять, на каком этапе сломалась "массажная ванночка для данных"? Здесь на помощь приходят логирование и обработка ошибок.

Помните, мы уже начинали знакомиться с тем, как в PostgreSQL и PL/pgSQL можно "общаться" и вести логи:

  • RAISE NOTICE: спокойный, дружеский тон — "Эй, тут всё хорошо, но тебе, возможно, захочется посмотреть на это".
  • RAISE WARNING: тон чуть громче — "Ой, тут что-то странное, возможно, можешь заглянуть".
  • RAISE EXCEPTION: паническая сирена — "СТОП! Алгоритм в беде! Мы остановили выполнение, чтобы всё не пошло прахом".

Каждый из этих уровней имеет своё предназначение, и важно правильно выбрать, какой из них использовать.

Вот как эти сообщения выглядят в коде:

DO $$
BEGIN
    -- Уровень NOTICE (всё нормально, просто уведомление)
    RAISE NOTICE 'Просто уведомление: началась обработка данных';

    -- Уровень WARNING (что-то подозрительное)
    RAISE WARNING 'Предупреждение: формат данных в столбце может быть некорректным';

    -- Уровень EXCEPTION (критическая ошибка)
    RAISE EXCEPTION 'Ошибка: входное значение недопустимо!';
END $$;

Когда использовать:

  • RAISE NOTICE — для отладки и спокойного вывода информации.
  • RAISE WARNING — чтобы предупредить о потенциально неправильных данных.
  • RAISE EXCEPTION — когда происходят критические ошибки, из-за которых выполнение функции должно быть остановлено.

Обработка ошибок с RAISE EXCEPTION

RAISE EXCEPTION — это ваш стоп-кран. Если что-то идет не так, вы сможете остановить выполнение функции и сообщить об ошибке.

Напомним, базовое использование выглядит так:

RAISE EXCEPTION 'Ваше сообщение об ошибке';

Но чтобы сделать сообщения более информативными, можно использовать переменные:

DECLARE
    input_value INTEGER;
BEGIN
    input_value := NULL;

    IF input_value IS NULL THEN
        RAISE EXCEPTION 'Ошибка: входное значение NULL. Ожидалось значение INTEGER';
    END IF;
END;

Форматирование сообщений

Вы можете подставлять переменные прямо в текст сообщения:

DECLARE
    var1 TEXT := 'Данные';
    var2 INTEGER := 42;
BEGIN
    RAISE EXCEPTION 'Ошибка при обработке % с ID %', var1, var2;
END;

Вывод: Ошибка при обработке Данные с ID 42.

Пример: валидация данных

Представьте, что у вас есть процедура, которая принимает возраст человека. Если возраст отрицательный, логично вызвать ошибку:

CREATE OR REPLACE FUNCTION validate_age(age INTEGER)
RETURNS VOID AS $$
BEGIN
    IF age < 0 THEN
        RAISE EXCEPTION 'Возраст не может быть отрицательным: %', age;
    END IF;
END;
$$ LANGUAGE plpgsql;

-- Вызов функции
SELECT validate_age(-5);  -- Вызовет ошибку

Информирование с RAISE NOTICE

Если RAISE EXCEPTION — это сирена, то RAISE NOTICE — это дружеское похлопывание по плечу. С помощью этого уровня можно добавлять комментарии для понимания того, что происходит внутри функции.

Когда использовать RAISE NOTICE:

  • Вывод отладочной информации (например, текущее состояние переменных).
  • Сообщение о начале выполнения этапа или результата вычислений.

Пример: информационные сообщения

CREATE OR REPLACE FUNCTION calculate_discount(price NUMERIC, discount_rate NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
    final_price NUMERIC;
BEGIN
    RAISE NOTICE 'Цена перед скидкой: %', price;
    RAISE NOTICE 'Ставка скидки: %', discount_rate;

    final_price := price - (price * discount_rate);

    RAISE NOTICE 'Итоговая цена: %', final_price;

    RETURN final_price;
END;
$$ LANGUAGE plpgsql;

-- Вызов функции
SELECT calculate_discount(100, 0.2);
-- Выводит:
-- NOTICE: Цена перед скидкой: 100
-- NOTICE: Ставка скидки: 0.2
-- NOTICE: Итоговая цена: 80

Практическое применение: планирование и логирование

Допустим, у вас есть сложная процедура обработки данных, и вы хотите знать, на каком этапе она сейчас находится:

CREATE OR REPLACE FUNCTION process_data_step_by_step()
RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Шаг 1: Подготовка данных';
    -- Ваша логика для первого этапа

    RAISE NOTICE 'Шаг 2: Валидация данных';
    -- Ваша логика для второго этапа

    RAISE NOTICE 'Шаг 3: Сохранение данных';
    -- Ваша логика для третьего этапа
END;
$$ LANGUAGE plpgsql;

-- Вызов функции
SELECT process_data_step_by_step();
-- В логах отобразится пошаговое выполнение

Приведём ещё один пример. Давайте представим магазин, который предлагает скидки только для заказов выше определенной суммы:

CREATE OR REPLACE FUNCTION apply_discount(order_amount NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
    IF order_amount < 50 THEN
        RAISE EXCEPTION 'Ошибка: сумма заказа должна быть не менее 50, текущая сумма: %', order_amount;
    END IF;

    RETURN order_amount * 0.9;  -- Применяем 10% скидку
END;
$$ LANGUAGE plpgsql;

-- Вызов функции
SELECT apply_discount(30);  -- Ошибка: сумма заказа должна быть не менее 50

Типичные ошибки

Ошибка 1: логирование сообщений без параметров.

Выглядит неинформативно, особенно в больших процедурах:

RAISE NOTICE 'Ошибка произошла';  -- Почему? Где? Как?

Рекомендация: всегда добавляйте контекст:

RAISE NOTICE 'Ошибка в функции process_data(): входное значение: %', input_value;

Ошибка 2: использование RAISE EXCEPTION там, где достаточно RAISE WARNING.

Если вы перестараетесь с исключениями, код будет прерываться по любому поводу, что затруднит обработку данных.

Совет: используйте уровни логирования осознано. Для отладки выбирайте NOTICE, а для критических моментов — EXCEPTION.

Ошибка 3: отсутствие логирования совсем.

Это как пытаться найти ключи в темной комнате. Без логов отладка сложных процессов становится почти невозможной.

Совет: добавляйте RAISE NOTICE на ключевых этапах выполнения функции, особенно если она большая и сложная.

2
Задача
SQL SELF, 55 уровень, 2 лекция
Недоступна
Логирование ошибок при валидации данных
Логирование ошибок при валидации данных
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Ra Уровень 35 Student
21 августа 2025
Тут и абзаца бы хватило