Уяви ситуацію, коли ти працюєш з базою даних, обробляєш купу транзакцій, а щось пішло не так. Користувач скаржиться, бізнес кричить, а ти навіть не бачиш, що саме трапилось. Ось тут і заходить у гру правильне логування помилок. Воно дозволяє:
- Зберігати помилки в базі для подальшого аналізу.
- Легко відновлювати деталі помилки: час її появи, повідомлення і пов’язані дані.
- Прокачувати свій код, працюючи над типовими помилками, які можна знайти при аналізі логів.
Коротше, логування — це як запис з камери спостереження для твоєї бази: бачиш усе, що пішло не так, і коли це сталося.
Створюємо таблицю error_log
Давай почнемо, як то кажуть, з фундаменту. Нам треба створити таблицю, в якій будемо зберігати інформацію про помилки. Таблиця матиме такі поля:
id— унікальний ідентифікатор помилки.error_message— текст помилки.error_time— час, коли сталася помилка.- (Додатково)
context— контекст помилки, якщо треба зберігати подробиці.
CREATE TABLE error_log (
id SERIAL PRIMARY KEY, -- Унікальний ідентифікатор помилки
error_message TEXT NOT NULL, -- Текстове повідомлення про помилку
error_time TIMESTAMP NOT NULL DEFAULT NOW(), -- Час виникнення помилки
context JSONB -- Додаткові дані про помилку
);
Що тут відбувається?
id SERIAL PRIMARY KEY— це поле створює унікальний ідентифікатор для кожного запису автоматично.error_message TEXT NOT NULL— тут буде зберігатися текст помилки. Поле обов’язкове для заповнення.error_time TIMESTAMP NOT NULL DEFAULT NOW()— поле, що фіксує час події. Якщо не вкажеш значення, воно автоматично запише поточний час завдякиDEFAULT NOW().context JSONB— опціонально, для зберігання додаткової інформації, наприклад, даних про операцію, де сталася помилка.
Після виконання команди CREATE TABLE у твоїй базі з’явиться структура для зберігання логів.
Приклад запису помилок у таблицю
Тепер, коли таблиця створена, перейдемо до практики: будемо зберігати інформацію про помилки у таблицю. Напишемо функцію, яка записує текст помилки і час у error_log.
Приклад функції для запису помилок
CREATE OR REPLACE FUNCTION log_error(p_error_message TEXT, p_context JSONB DEFAULT NULL)
RETURNS VOID AS $$
BEGIN
INSERT INTO error_log (error_message, context)
VALUES (p_error_message, p_context);
END;
$$ LANGUAGE plpgsql;
p_error_message— вхідний параметр, куди передається текст помилки.p_context— опціональний параметр для передачі додаткових даних. За замовчуванням має значенняNULL.INSERT INTO error_log (error_message, context)— додає новий запис у таблицюerror_log.DEFAULT NULL— якщо контекст не заданий, поле заповнюєтьсяNULL.
Тепер, якщо треба записати повідомлення про помилку, можеш викликати функцію так:
SELECT log_error('Помилка при виконанні запиту', '{"query": "SELECT * FROM data"}');
Це додасть новий запис у таблицю error_log.
Автоматичне логування помилок
Писати кожного разу SELECT log_error(...) вручну може бути незручно. Давай автоматизуємо цей процес з використанням обробки виключень.
Приклад функції з обробкою виключень.
CREATE OR REPLACE FUNCTION divide_numbers(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
DECLARE
result NUMERIC;
BEGIN
-- Спробуємо виконати ділення
result := a / b;
-- Повертаємо результат
RETURN result;
EXCEPTION
WHEN division_by_zero THEN
-- Логуємо помилку і передаємо контекст
PERFORM log_error('Ділення на нуль', jsonb_build_object('a', a, 'b', b));
-- Генеруємо виключення для користувача
RAISE EXCEPTION 'Ділення % на % неможливе — дільник дорівнює нулю', a, b;
END;
$$ LANGUAGE plpgsql;
- Перевірка ділення: виконується
result := a / b. Якщоb = 0, PostgreSQL кидає виключенняdivision_by_zero. - Обробник виключень (
EXCEPTION) перехоплює помилку. - Всередині обробника викликаємо функцію
log_error, щоб записати помилку у таблицю разом з параметрами, які спричинили проблему. - Після запису помилки за допомогою
RAISE EXCEPTIONвикликається нове повідомлення про помилку, щоб користувач теж отримав сповіщення.
Приклад виклику:
SELECT divide_numbers(10, 0);
Результат:
- Користувач побачить помилку:
Ділення 10 на 0 неможливе — дільник дорівнює нулю. - У таблиці
error_logз’явиться запис про ділення на нуль.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ