# Поиск и исправление багов с Claude Code: практическое руководство

> Полное практическое руководство по отладке кода через Claude Code: анализ stack traces, разбор логов сервера, устранение ошибок TypeScript, починка тестов и ликвидация узких мест производительности.

## 1. Почему отладка с Claude Code эффективнее традиционного дебага

Классический поиск дефектов часто превращается в изнурительную рутину: разработчик часами продирается сквозь запутанные логи терминала, вручную расставляет десятки `console.log` или точек останова дебагера и пытается увязать данные из множества модулей.

Терминальный агент Claude Code в корне меняет этот подход: обладая прямым доступом к локальной файловой системе проекта, он способен мгновенно проследить цепочку выполнения от клиентского интерфейса через контроллеры бэкенда до запросов в базу данных.

```mermaid
flowchart TD
    A["Симптом: Ошибка или аварийный лог"] --> B["Claude Code CLI"]
    B --> C["Анализ Stack Trace & Выделение файлов"]
    C --> D["Read & Grep по кодовой базе"]
    D --> E["Локализация первопричины сбоя"]
    E --> F["Формулирование гипотезы и патча"]
    F --> G["Автоматический прогон тестов / сборки"]
    G -->|Успех| H["Чистый коммит фикса"]
    G -->|Ошибка| E
```

### Сравнение ручного дебага и отладки с Claude Code

| Критерий | Традиционная ручная отладка | Отладка через Claude Code |
| :--- | :--- | :--- |
| **Локализация сбоя** | Ручной переход по строкам стека в IDE | Автоматическое сопоставление ошибки с контекстом проекта |
| **Работа с логами** | Визуальный поиск аномалий среди тысяч строк текста | Автономный анализ структурированных логов через пайплайны CLI |
| **Сложные взаимосвязи** | Необходимость удерживать в памяти граф вызовов 5-10 файлов | Пошаговое семантическое отслеживание потоков данных |
| **Ошибки TypeScript** | Соблазн заглушить компилятор через `as any` | Корректное сужение типов без нарушения типобезопасности |
| **Верификация решения** | Ручной перезапуск сервера или повторный ввод команд тестов | Автоматический циклический перезапуск тестов до 100% успеха |

> [!NOTE]
> Claude Code не заменяет инженерное мышление разработчика, но сокращает время от фиксации инцидента до нахождения его причины в 3–5 раз.

---

## 2. Анатомия идеального баг-репорта для AI-ассистента

Скорость и точность решения проблемы напрямую зависят от того, насколько полно описан дефект во входном запросе.

### Размытый запрос против структурированного описания

> [!WARNING]
> **Неэффективный запрос:**
> *«Приложение сломалось, форма регистрации не работает, посмотри что там не так.»*
> 
> Получив такую формулировку, агент вынужден наугад перебирать десятки файлов, расходуя контекстное окно на догадки.

> [!TIP]
> **Профессиональное инженерное описание:**
> *«При отправке формы на `/register` клиент получает статус 500. В консоли браузера падает ошибка: `TypeError: Cannot read properties of undefined (reading 'email')`. Запрос отправляет JSON с полями `username` и `mailAddress`. Проверь схему валидации в `src/api/auth.ts` и согласуй наименования полей.»*

### Четыре правила исчерпывающего описания дефекта

1. **Ожидаемое поведение (Expected Behavior):** что именно должно было произойти при нормальном сценарии.
2. **Фактическое поведение (Actual Behavior):** точный текст ошибки, HTTP-код статуса или некорректный результат вычислений.
3. **Шаги воспроизведения (Reproduction Steps):** какие кнопки были нажаты, какие параметры переданы в URL или тело запроса.
4. **Контекст локализации (Context & File Paths):** на какой странице, в каком компоненте или API-маршруте происходит сбой.

---

## 3. Анализ Stack Traces и разбор сообщений об ошибках

Сообщения об ошибках и стеки вызовов можно передавать агенту в исходном виде. Claude самостоятельно отфильтрует шум библиотек (`node_modules`) и сфокусируется на коде вашего репозитория.

### Передача сырого стека ошибки

```text
I am getting this runtime error when rendering the user table:

TypeError: Cannot read properties of undefined (reading 'map')
    at UserTable (src/components/UserTable.tsx:34:22)
    at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:15486:18)
    at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:20103:13)

What is causing this, and how should we properly handle loading and empty states?
```

### Как Claude расследует подобный инцидент

1. **Целевое чтение:** открывает `src/components/UserTable.tsx` на строке 34 с помощью инструмента `Read`.
2. **Анализ источника данных:** проверяет пропсы и хуки состояния (`useState`, `useQuery`), выясняя, почему массив пользователей в момент рендера равен `undefined`.
3. **Безопасное исправление:** добавляет опциональную цепочку (`users?.map(...)`), индикатор загрузки (Skeleton/Spinner) или безопасное значение по умолчанию (`users = []`).

---

## 4. Работа с логами сервера и анализ через конвейер CLI

Для исследования серверных сбоев на локальном стенде или staging-сервере Claude Code можно подключать напрямую к стандартным потокам ввода-вывода Unix.

### Анализ логов через консольный пайплайн

```bash
# Передать последние 100 строк лога Nginx в Claude для мгновенной диагностики
tail -n 100 /var/log/nginx/error.log | claude -p "Find critical errors and explain their root cause. Provide actionable fix instructions."

# Поиск ошибок конкретного контейнера Docker
docker logs --tail 200 api-service 2>&1 | claude -p "Analyze database connection failures and timeout exceptions."
```

### Интерактивное исследование лог-файлов

В интерактивной сессии вы можете направить агента на сохраненный файл:

```text
Read logs/production-error.log and focus on entries with status 500 from the last two hours. Group related exceptions and trace which external service call failed.
```

Claude выделит повторяющиеся паттерны сбоев, выявит проблемы авторизации внешних API или исчерпание пула соединений с базой данных.

---

## 5. Стратегическое инструментирование: точечное логирование и трассировка

Сложнее всего выявлять «тихие баги» (Silent Bugs), когда приложение не выбрасывает исключений, но возвращает неверный бизнес-результат (например, итоговая стоимость заказа рассчитывается как `$0.00` вместо `$42.50`).

В таких случаях применяется метод стратегического инструментирования.

### Пошаговый алгоритм расследования

1. **Поставьте задачу на расстановку логов:**
   ```text
   The order total calculation is returning 0 for items with promo codes. Add targeted diagnostic logging to calculateOrderTotal and its call sites to log input arguments, discount factors, and return values.
   ```
2. **Воспроизведите баг:** оформите тестовый заказ с промокодом в среде разработки.
3. **Передайте полученные диагностические логи обратно агенту:**
   ```text
   Here is the diagnostic log from the checkout attempt:
   [DEBUG] Item subtotal: 42.50
   [DEBUG] Promo code applied: 'SPRING20' -> parsed discount: '0.2' (string)
   [DEBUG] Applying formula: 42.50 * (1 - '0.2') -> NaN -> coerced to 0

   What went wrong?
   ```
4. **Исправление и очистка:**
   Claude мгновенно укажет на несовпадение типов (строка вместо числа), исправит логику парсинга и **самостоятельно удалит все временные отладочные логи**.

---

## 6. Исправление сложных ошибок типов в TypeScript

Ошибки компилятора TypeScript часто вызывают трудности при работе с дженериками, сложными объединениями (Unions) или вложенными структурами.

### Почему опасно «глушить» компилятор

Многие разработчики в спешке прибегают к принудительному приведению типов (`as unknown as TargetType`), что маскирует проблему на этапе сборки, но гарантированно приводит к падениям в рантайме.

:::tabs
@tab Небезопасный подход (Type Casting)
```typescript
// Плохо: принудительное приведение скрывает реальную ошибку
const userEmail = (response.data as any).user.email;
// Если user окажется null, приложение аварийно упадет в проде!
```
@tab Корректное сужение типов (Type Narrowing)
```typescript
// Хорошо: безопасное сужение типов через защитники (Type Guards)
if (!response.data || typeof response.data !== 'object' || !('user' in response.data)) {
  throw new Error('Invalid API response structure');
}
const userEmail = response.data.user?.email ?? 'anonymous';
```
:::

### Инструкция для Claude по чистому решению

```text
I am encountering this TypeScript compiler error in src/services/payment.ts:48:

Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.

Fix this issue properly using strict type narrowing or safe fallback values. Do NOT use type assertions ('as') or 'any'.
```

Claude проверит жизненный цикл переменной и добавит корректную проверку на отсутствие данных.

---

## 7. Автоматизированный ремонт сборки и тестов в цикле

Одна из мощнейших возможностей Claude Code — автономная работа в цикле «Запуск → Анализ → Исправление → Проверка».

```mermaid
flowchart TD
    A["Команда: 'Fix all failing tests'"] --> B["Запуск npm test через Bash"]
    B --> C{"Все тесты пройдены?"}
    C -->|Да| D["Отчет об успешном завершении"]
    C -->|Нет| E["Анализ ошибок в отчете тест-раннера"]
    E --> F{"Где баг: в коде или в тесте?"}
    F -->|В коде| G["Исправление бизнес-логики"]
    F -->|В тесте| H["Обновление устаревших ожиданий теста"]
    G & H --> B
```

### Готовые шаблоны команд для починки кода

:::tabs
@tab Модульные тесты (Jest / Vitest)
```text
Run the test suite with npm test. For each failing test:
1. Determine if the failure is caused by a real bug or an outdated test expectation.
2. Fix the underlying issue cleanly.
3. Re-run tests until all test suites pass.
```
@tab Ошибки сборки проекта
```text
Run npm run build. Inspect the compiler and bundler error output. Fix all type and syntax errors, then verify with a clean build.
```
@tab Ошибки линтера (ESLint)
```text
Run npx eslint src/ --max-warnings=0. Fix all reportable style and syntax errors without disabling ESLint rules.
```
:::

---

## 8. Поиск узких мест производительности и утечек ресурсов

Ошибки — это не только аварийные завершения. Медленная загрузка страниц, избыточные запросы к базе данных и зависания интерфейса — это критические дефекты производительности.

### Запрос на аудит быстродействия

```text
The /dashboard page takes over 6 seconds to load. Analyze the server-side data fetching and client components:
1. Check for N+1 query patterns in our Prisma calls.
2. Identify missing database indices on frequently queried foreign keys.
3. Look for unnecessary client component re-renders caused by unstable object references.
```

### Что Claude выявляет при анализе производительности

- **N+1 запросы:** замена циклов запросов к БД пакетной выборкой через оператор `IN` или связь `include`.
- **Мемоизация в React:** нахождение тяжелых вычислений без `useMemo` или нестабильных коллбэков без `useCallback`.
- **Избыточный объем данных:** внедрение пагинации (`limit`/`offset`) или селективной проекции (`select: { id: true, name: true }`) вместо выборки всех колонок таблицы.

---

## 9. Практический воркшоп: пошаговое расследование реального бага

Разберем практический кейс: пользователи жалуются, что при применении скидочного купона 15% в корзине из трех товаров итоговая сумма списывается некорректно.

### Шаг 1. Локализация логики расчета

Откройте Claude Code и найдите нужный модуль:

```text
Find where the cart discount calculation is implemented and inspect the file.
```

Claude использует `Grep` по ключевому слову `discount` и обнаруживает файл `src/domain/cart.ts`.

### Шаг 2. Анализ дефектного кода

```typescript
// Найденный фрагмент в src/domain/cart.ts:
export function applyCoupon(total: number, discountPercent: number): number {
  return total - total * (discountPercent / 100);
}
```

На первый взгляд формула верна. Однако в JavaScript операции с плавающей точкой приводят к артефактам точности: `100 - 100 * (15 / 100)` дает `85.00000000000001`, из-за чего платежный шлюз Stripe (ожидающий целые центы) отклоняет платеж.

### Шаг 3. Постановка задачи на исправление и тесты

```text
In src/domain/cart.ts, the applyCoupon function causes floating-point precision issues that fail payment validation. Refactor it to calculate prices in integer cents, add rounding via Math.round, and create a comprehensive unit test in src/domain/cart.test.ts covering edge cases.
```

### Шаг 4. Верификация результата

Агент исправляет функцию:

```typescript
export function applyCouponInCents(totalCents: number, discountPercent: number): number {
  const discountAmount = Math.round(totalCents * (discountPercent / 100));
  return Math.max(0, totalCents - discountAmount);
}
```

После этого Claude самостоятельно запускает `npm test src/domain/cart.test.ts` через `Bash` и подтверждает успешность всех тестов.

---

## 10. Быстрая самопроверка и итоговый чек-лист дебага

Проверьте свои знания по методикам отладки с Claude Code.

### Контрольные вопросы

> **1. Какой способ исследования серверного сбоя на staging-сервере является наиболее эффективным?**
>
> > [!TIP]
> > **Ответ:** Передать последние строки лога напрямую в автономный режим Claude Code через консольный пайплайн: `tail -n 150 /var/log/app.log | claude -p "Find errors and diagnose causes"`.

> **2. Почему при устранении ошибок TypeScript следует явно запрещать ассистенту использовать оператор `as`?**
>
> > [!TIP]
> > **Ответ:** Приведение типов через `as` лишь скрывает проблему от компилятора, но не защищает приложение от аварийных падений в рантайме. Необходимо требовать безопасного сужения типов (Type Narrowing) или значений по умолчанию.

> **3. Как правильно организовать исправление группы упавших тестов после рефакторинга?**
>
> > [!TIP]
> > **Ответ:** Запустить Claude Code в циклическом режиме с инструкцией: прогнать тесты, отличить устаревшие ожидания тестов от реальных дефектов кода, устранить первопричины и повторять прогон до 100% успеха.

### Итоговый чек-лист системной охоты на баги

- [ ] Передавайте агенту 4 ключевых элемента: Ожидаемое поведение, Фактическое поведение, Шаги воспроизведения и Пути к файлам.
- [ ] Предоставляйте полные stack traces без сокращений — Claude сам отфильтрует системный шум.
- [ ] Используйте Unix-пайпы (`tail | claude -p`) для быстрой диагностики логов сервера.
- [ ] Требуйте безопасного сужения типов вместо принудительного приведения `as any`.
- [ ] Поручайте Claude создавать регрессионные тесты на каждый исправленный дефект.
- [ ] Удаляйте временные отладочные логи перед фиксацией изменений в Git.