Обработка ошибок в коде: чтобы ничего не падало молча
Сломалось - узнать должен ты. Не клиент в гневном письме через неделю.
Обработка ошибок для вайбкодеров: понятное сообщение людям, полный лог тебе, умные повторы запросов и готовый промпт, чтобы агент не прятал сбои.
Что такое обработка ошибок простыми словами
Представь, что дома прорвало трубу. Дальше - два сценария.
Первый: где-то под полом тихо капает вода. Ни звука, ни сигнала. Ты живёшь спокойно месяц - а потом находишь сгнивший пол и потоп у соседей снизу. Авария была. А ты узнал последним.
Второй: труба дала течь - и сразу заорал датчик, перекрылся кран, на телефон прилетело уведомление. Неприятно? Ещё бы. Но ты починил всё за час, пока проблема была размером с лужицу.
Вот это и есть обработка ошибок. Программа всегда где-нибудь ломается - это так же неизбежно, как дождь. Вопрос один: ты узнаешь об этом сразу и по-человечески - или потом и катастрофой?
Почему вайбкодеру важно обрабатывать ошибки
Ты вайбкодер. Код за тебя пишет агент. Но именно ты решаешь, как приложение ведёт себя, когда что-то идёт не так - а так оно идёт постоянно: интернет моргнул, человек ввёл ерунду, чужой сервис прилёг отдохнуть.
Не задашь агенту правила про ошибки - он по умолчанию выберет самое опасное. Спрячет их. Снаружи всё работает, а внутри тихо капает.
- Пользователь видит белый экран или вечную крутилку - и уходит молча. Даже не напишет тебе.
- Ты не понимаешь, что сломалось: ошибка нигде не оставила следа.
- Один крошечный сбой роняет всё приложение - хотя мог бы остаться локальной мелочью.
Разница между «у меня сайт иногда глючит, не знаю почему» и «я вижу каждую проблему в логах и чиню за минуту» - это и есть культура обработки ошибок. Хорошая новость: правила простые. Один раз вшил в промпт - и забыл.
Пять правил хорошей обработки ошибок
В скилле по обработке ошибок есть пять железных принципов. Разберём каждый на пальцах.
1. Падай быстро и громко
Самое вредное - это глотать ошибку Глотать ошибку (swallow) - поймать сбой и ничего с ним не сделать: ни показать, ни записать, ни передать дальше. Программа делает вид, что всё хорошо, хотя это не так. . Сломалось - значит, должно всплыть прямо там, где случилось. А не быть закопано поглубже «чтобы никого не пугать».
Звучит банально. Но именно здесь новички (и ленивые агенты) спотыкаются чаще всего: ставят блок ловли ошибки - и оставляют его пустым. Это как заклеить мигающую лампочку «check engine» изолентой. Лампочка не мигает - значит, всё хорошо, да? Да-да.
2. Человеку - одно сообщение, тебе - другое
На одну и ту же ошибку нужны два разных текста:
- Человеку - коротко и вежливо: «Что-то пошло не так, попробуй позже». Без технических подробностей, без страшных слов, без кусков кода на экране.
- Тебе в лог - вся подноготная: что именно упало, где и с какими данными. Это твой датчик протечки.
3. У ошибки должно быть имя, а не просто текст
Плохая ошибка - это голая строчка "что-то сломалось". По ней не понять ровным счётом ничего.
Хорошая ошибка - типизированная Типизированная ошибка - ошибка не как случайная строка текста, а как объект с понятным названием и кодом: например NotFound (не найдено), Unauthorized (нет доступа), RateLimited (слишком часто). По коду сразу ясно, что случилось и как реагировать. : у неё есть код и понятное имя. Смотри:
NotFound- запрошенного нет.Unauthorized- нужно войти в аккаунт.ValidationError- человек ввёл что-то не то.RateLimited- слишком много запросов подряд, пора притормозить.
Когда ошибки именованные, приложение точно знает, что показать человеку и какой ответ вернуть. «Не найдено» - это совсем не то же самое, что «нет доступа» или «наш сервер прилёг».
4. Повторяй запрос с умом, а не лбом в стену
Иногда ошибка временная: интернет моргнул, сервис на секунду подвис. Тут уместен повтор с нарастающей паузой Повтор с нарастающей паузой (retry with backoff) - если запрос не прошёл, попробовать ещё раз, но не сразу, а через паузу, которая с каждой попыткой увеличивается. Так ты не заваливаешь сервер очередью одинаковых запросов. : попробовал ещё разок, не вышло - подождал чуть дольше, и так несколько раз.
Но повторять можно далеко не всё:
- Сеть моргнула, таймаут соединения - само может починиться через секунду.
- Чужой сервер ответил «я временно перегружен» - подожди и повтори.
- Повтор с растущей паузой, а не очередью подряд - даёшь системе выдохнуть.
- Человек ввёл неверный пароль - повтор не поможет, пароль сам не исправится.
- «Не найдено» - чего нет, того нет, спрашивай хоть сто раз.
- Бесконечные повторы без лимита - добьёшь чужой сервер и зависнешь сам.
5. Ошибка - часть договора с тем, кто пользуется кодом
Умеет приложение вернуть ошибку «нет доступа» или «слишком много запросов» - пусть делает это в одном понятном формате каждый раз. Тогда и фронтенд, и ты сам, и будущий агент всегда знают, чего ждать. Хаотичные, разные на вид ошибки - это второй источник боли сразу после молчаливых.
Пример из жизни: форма, которая молча теряла заявки
Ты собрал с агентом форму обратной связи на сайте. Потыкал - работает. Выложил. Через неделю замечаешь: заявок ноль. Хотя счётчик уверяет, что форму открывали десятки людей.
Что произошло на самом деле:
- У сервиса отправки писем кончился лимит - он начал возвращать ошибку.
- Агент по умолчанию обернул отправку в блок ловли ошибки и оставил его пустым.
- Поэтому человек видел бодрое «Спасибо, заявка отправлена!» - а письмо никуда не летело. Тихо капало под полом целую неделю.
Как застраховаться с самого старта? Просто выдай агенту правила. Вот готовый промпт:
Когда пишешь любой код, который может сломаться (запросы в сеть, работа с базой, отправка писем, ввод пользователя), соблюдай правила:
-
Никогда не оставляй пустой блок обработки ошибки. Каждый такой блок должен либо корректно обработать сбой, либо передать его дальше, либо записать в лог.
-
На каждую ошибку делай два сообщения. Пользователю - короткое и вежливое, без технических деталей. В лог - полную информацию: что упало, где и с какими данными.
-
Не показывай пользователю успех, пока действие реально не выполнилось. Если письмо не ушло - скажи честно, что не получилось, и предложи повторить.
-
Используй понятные типы ошибок с кодом: не найдено, нет доступа, неверный ввод, слишком много запросов, внутренняя ошибка.
-
Повторяй запрос автоматически только если он мог упасть случайно (сеть, таймаут). Делай повтор с нарастающей паузой и ограничь число попыток тремя. Ошибки ввода и доступа не повторяй.
В конце покажи мне список мест, где код может упасть, и как ты в каждом из них обрабатываешь ошибку.
Здоровая и больная обработка ошибок: сравнение
- Каждый сбой где-то всплывает: в логе, на экране или выше по коду.
- Человек видит понятное сообщение, а не стектрейс на пол-экрана.
- В логах есть вся техническая правда - ты чинишь по факту, а не гадаешь на кофейной гуще.
- Повторяются только временные сбои, с паузой и лимитом попыток.
- Пустые блоки «поймал и молчу» - ошибки исчезают бесследно.
- Человеку вываливается кусок кода или белый экран.
- Одна мелкая ошибка роняет всё приложение целиком.
- В лог попали пароли или ключи - а сам лог потом куда-то утёк.
Чек-лист: молчит ли твоё приложение об ошибках
Прежде чем выкатывать что-то людям, прогони по чек-листу:
- Что увидит человек, если это сломается? Ответ «белый экран» или «не знаю» - плохо.
- Где я увижу, что это сломалось? Если нигде - добавь лог.
- Нет ли пустых блоков обработки ошибок? Попроси агента показать все места ловли ошибки и что в них происходит.
- Не показываю ли я успех раньше времени? «Отправлено» должно появляться только после реальной отправки.
- Не утекли ли секреты в логи? Паролям, токенам и ключам в логах не место.
Частые ошибки новичка в обработке ошибок
- Оставлять блок ловли ошибки пустым. Самая опасная привычка на свете. Ошибка исчезает, проблема растёт в темноте.
- Показывать человеку технический текст. Стектрейс на экране пугает обычных людей и помогает злоумышленникам. Им - вежливое сообщение, тебе - лог.
- Врать про успех. «Готово!» до того, как действие реально случилось, - прямая дорога к потерянным заявкам и заказам.
- Повторять то, что повтором не чинится. Неверный пароль или «не найдено» сто раз подряд - пустая трата сил и нагрузка на сервер.
- Бесконечные повторы без лимита. Добьёшь чужой сервис, а заодно подвесишь и своё приложение.
- Логировать секреты. Соблазнительно записать «весь запрос целиком», но туда часто прилетают пароли и ключи. Вычищай чувствительное.
TL;DR - если коротко
- Молчаливая ошибка - худшая. Сбой должен кричать там, где случился, а не уходить под ковёр.
- Два текста на одну ошибку: человеку - вежливое «упс, попробуй позже», тебе в лог - вся подноготная.
- Пустой блок ловли ошибки - это бомба. Каждый обязан обработать, пробросить дальше или записать в лог.
- Имя вместо безликой строки. Типизированные ошибки с кодом: NotFound, Unauthorized, RateLimited.
- Повторяй с головой. Только то, что чинится само, с растущей паузой и лимитом - а не лбом в стену.
- Перед публикацией - чек-лист. Что увидит человек, где увидишь ты, нет ли пустых блоков, не врёшь ли про успех.