Обработка ошибок в dbExpress

Тишина в эфире, или как мы чуть не потеряли доверие клиента
Я помню тот холодный вторник так, будто это было вчера. Мы запускали очередную сборку для небольшого логистического склада — казалось бы, рутина. Клиент сидел рядом, попивая кофе, и вдруг экран погас. Ни сообщения, ни ошибки — просто черное окно. Через секунду — «Access violation». У него дернулась рука с чашкой. «Вы что, мои данные стерли?» — спросил он с такой интонацией, от которой внутри всё сжалось. Это был не технический сбой. Это было унижение.
Проблема, как выяснилось позже, крылась в нашей наивной обработке ошибок в dbExpress. Мы просто оборачивали вызовы в try-except, глотали EDBEngineError и писали в лог. Но лог-файл валялся на сервере, а клиент видел пустой экран. Мы не сказали ему ни слова. Он почувствовал себя обманутым, а нас — дилетантами. С того момента мы поклялись: обработка ошибок — это диалог с пользователем, а не техническая запись.
«Не удалось подключиться» — это приговор?
Знаете, что чувствует разработчик, когда после трёх часов отладки видит в журнале „Connection failed“? Это смесь ярости и беспомощности. Но когда то же самое видит бизнес-пользователь, у которого завис отчёт перед налоговой — это паника. Однажды наш DbExpress-компонент TSQLConnection молча возвращал „Database error“ без каких-либо подробностей. Клиент позвонил нам с криком: «У вас система сломалась! Почему вы не предупредили?» А мы даже не знали, что он в этот момент работал. Провода горели. Мы поняли: нужно не просто ловить исключение, а немедленно показывать человеческое сообщение.
- Первый шаг: мы добавили всплывающее окно с текстом «Не удалось соединиться с базой. Проверьте кабель и доступ к серверу». Клиент сразу успокоился — он понял, что проблема не в данных, а в сети.
- Второй шаг: в коде мы перестали использовать пустой
on E: Exception do— это как запереть человека в тёмной комнате без фонарика. Вместо этого мы разводили EDatabaseError и делали релоггин с повторной попыткой.
Эмоции на кону: как один dbExpress-запрос едва не сорвал тендер
История, которая научила нас уважать исключения. Мы разрабатывали модуль для складского учёта — нужно было выполнить сложный bulk-insert через TSQLQuery. Во время демонстрации потенциальному заказчику (важный тендер!) база данных выдала „Deadlock victim“. И — тишина. Никто не знал, что делать. Я сидел за клавиатурой, чувствуя, как учащается пульс. Мой коллега побледнел. Заказчик напрягся. Через секунду я нажал «Повторить» — без кода, просто перезапуск приложения. Чудом всё прошло, но осадок остался.
После этой нервотрёпки мы встроили в каждую транзакцию механизм повторных попыток с экспоненциальной задержкой. И самое главное — мы стали сообщать пользователю, что происходит: «Обнаружен конфликт блокировок. Система автоматически повторит запрос через 3 секунды». Знаете, что изменилось? Вместо страха клиент чувствовал контроль. Даже когда система тормозила, он видел: она борется. Это спасло не один десяток нервных клеток — и наших, и заказчиков.
Что мы чувствуем, когда ловим исключение в dbExpress?
Честно: в первую очередь — страх. Страх, что данные повреждены, что пользователь остался без связи с сервером, что мы сейчас покажем «Internal Server Error» в лице клиенту. Но со временем страх превратился в уважение. Каждый EDBEngineError — это весточка от СУБД. Она кричит: «Эй, программист! Тут проблема!» И наш долг — не заткнуть ей рот, а перевести её крик на человеческий язык. Мы научились смотреть на стэк-трейс не как на врага, а как на карту сокровищ. Теперь, когда вижу ошибку подключения, я чувствую азарт: «Ага, сеть упала. Сейчас мы это обернём в красивую реконнект-логику и удивим пользователя плавным восстановлением».
Правила, которые родила боль (и которые мы теперь не нарушаем)
- Никаких пустых try-except. Если ты ловишь исключение — ты должен что-то сделать: откатить транзакцию, показать сообщение, записать детали в лог. Молчание = враг.
- EDBEngineError — наш друг. В dbExpress ErrorCode и ErrorMessage часто содержат точную причину. Мы парсим их и показываем пользователю понятный текст, а не код «0x80004005».
- Всегда завершай транзакцию. Если исключение вылетело, а ты забыл Rollback — следующий запрос упадёт с „Cannot perform this operation on a closed dataset“. Это чувство, когда хочешь провалиться сквозь землю, знакомо каждому.
- Сообщай прогресс. Если dbExpress молчит 30 секунд — пользователь думает, что всё зависло. Мы добавили индикацию: «Выполняется запрос... Ожидание ответа от сервера». Это снижает тревожность до нуля.
Момент истины: когда база «упала», а клиент улыбнулся
Недавно случился сбой питания на сервере. Вся база ушла в офлайн. Я открыл приложение — и оно показало: «Потеряна связь с базой. Приложение автоматически переподключится через 5 секунд». Клиент посмотрел на экран, пожал плечами: «Ну, бывает». Через 20 секунд всё восстановилось само. Он даже не успел расстроиться. Тогда я понял: правильная обработка ошибок — это не технология, это уважение к человеку. Мы перестали быть «магами за кулисами», которые колдуют над логами. Мы стали партнёрами, которые говорят: «Я вижу проблему, я решаю её, вот что происходит». Это изменило всё — от отношений с клиентами до собственного спокойствия по ночам.
С тех пор каждая ошибка dbExpress для нас — не «фатал», а приглашение к диалогу.
Добавлено: 27.04.2026
