Модуль 5 · Урок 14 · ~10 минут

Философия ошибок

Одна идея этого урока: лучшее место для борьбы с ошибкой – дизайн, в котором она невозможна.

Знакомая ситуация

Ты просишь агента: «сделай, чтобы планировщик не падал». Агент послушно оборачивает каждый шаг проверками. Код раздувается вдвое, читать его стало тяжело – а через неделю пользователь жалуется: «нажал кнопку, ничего не произошло». Смотришь в лог – пусто. Ошибка была, агент её поймал... и молча проглотил.

Это классика: с ошибками начали бороться, вместо того чтобы их проектировать.

Обработка ошибок – один из главных источников сложности. Оустерхаут: сначала определи ошибки прочь из существования (define errors out of existence), и только то, что осталось, обрабатывай – в одном месте, громко и понятно.

Иерархия работы с ошибками

У сеньора есть чёткий порядок предпочтений. Каждый следующий уровень – только если предыдущий невозможен:

1
Сделать ошибку невозможной по дизайну define errors out of existenceПример Оустерхаута: «удали файл» при отсутствующем файле – не ошибка, а успех: файла нет, цель достигнута. Твой случай: «отпиши студента от рассылки», когда он уже отписан – это успех, а не сбой. Меняешь определение операции – и целый класс ошибок исчезает.
2
Обработать в одном месте error aggregationНе двадцать проверок по всему коду, а один общий обработчик: любая непойманная ошибка попадает туда, логируется и превращается в понятный ответ пользователю. Меньше дублей – меньше сложности.
3
Упасть громко и рано fail fastЕсли продолжать бессмысленно (нет ключа API, нет доступа к базе) – лучше остановиться сразу с внятным сообщением, чем ковылять дальше и портить данные. Тихая деградация данных страшнее громкого падения.

Две аудитории одного сообщения

Каждая ошибка говорит с двумя разными слушателями, и им нужны разные тексты:

Пользователю – что делать дальше. Не «Error 500», а «Не удалось сохранить план. Попробуй ещё раз или напиши в поддержку». Без технических деталей, с ясным следующим шагом.

В лог – что случилось технически. Какой запрос, какие данные, какой ответ пришёл от внешнего сервиса. Всё, что понадобится тебе или агенту, чтобы найти причину за минуты, а не часы.

Худший вариант – молча проглотить. ИИ-агенты это любят: обернуть вызов, а в ветке ошибки оставить пустоту. Приложение «не падает», но и не работает – и никто не знает, почему. Проглоченная ошибка отнимает больше времени, чем десять громких.

Как думают три уровня

Джун · ловит как попалоГде-то ошибки не обработаны вовсе, где-то проглочены «чтобы не падало». Сообщения – технический жаргон наружу или тишина. Каждый инцидент – детектив без улик.
Мидл · обрабатывает всё подрядПроверки на каждом шагу, код тонет в защитных конструкциях. Ошибки пойманы, но сложность выросла, а что видит пользователь – по-прежнему лотерея. Борется с симптомами, не с причиной.
Сеньор · меняет дизайнСначала спрашивает: «какие из этих ошибок можно определить прочь из существования?». Оставшиеся стягивает в одно место, критичные роняют систему громко и рано. Ошибок в коде меньше, а надёжность выше.

Проверь себя

1. В планировщике кнопка «удалить задачу» иногда выдаёт ошибку: задача уже удалена с другого устройства. Агент предлагает показывать «Ошибка: задача не найдена». Что предложит сеньор?

2. Студентка пишет: «нажимаю оплатить – ничего не происходит». В логах приложения пусто. Какова самая вероятная причина?

3. Приложение стартует, хотя ключ платёжного API не задан – ошибка всплывёт при первой оплате. Агент говорит: «зато сервис доступен». Позиция сеньора?

Что говорить агенту уже сегодня

Источники