| name | error-handling-discipline |
| description | Дисциплина ошибок: ловим ожидаемые исключения (LLMError/ToolError/TimeoutError), нет необработанных, пользователю — человеческое сообщение, stacktrace только в лог. |
Skill: error-handling-discipline
Правила обработки ошибок. Источник истины — _docs/instructions.md §5 и §6, _docs/architecture.md §2.
Когда использовать
- Пишешь или меняешь handler, tool, агентный цикл или сервис с внешним I/O.
- Добавляешь новый класс ошибок или новую внешнюю интеграцию.
- Формируешь сообщение пользователю при сбое.
Алгоритм
- Нет необработанных исключений (NFR-3). Каждый handler / tool / агентный цикл либо сам ловит ожидаемые (
LLMError, ToolError, asyncio.TimeoutError), либо полагается на глобальный error handler в Dispatcher.
- Переиспользуй существующие иерархии, не плоди новые в обход:
app/services/llm.py: LLMError → LLMTimeout / LLMUnavailable / LLMBadResponse.
app/tools/errors.py: ToolError → ToolNotFound / ArgsValidationError.
- Пользователю — человеческое сообщение, без stacktrace и внутренних деталей. Текст — по §1 (русский).
- Stacktrace — только в лог:
logger.exception(...) или logger.error(..., exc_info=True). Чувствительные данные в лог не пишем (§6).
- Отказоустойчивость по слоям. Таймаут LLM, сетевой сбой, недоступность Ollama, битый JSON, упавший tool, превышение лимита шагов — каждый ловится и превращается в понятное сообщение + запись в лог (
_docs/architecture.md §2).
- Деградация, а не падение. Где это предусмотрено (авто-подгрузка архива,
Planner/Critic) — WARNING и продолжение с последним доступным результатом, а не исключение наружу.
Чего избегать
- Голого
except Exception: pass и проглоченных ошибок без лога.
- Stacktrace и внутренних путей в сообщении пользователю (см.
prompt-injection-defense).
- Новых ad-hoc классов ошибок вместо существующих иерархий.
- Необработанного I/O, способного уронить агентный цикл.