Programowanie sterowane błędami
Programowanie sterowane błędami traktuje każdy błąd kompilatora, nieudany test lub wyjątek w runtime jako precyzyjną, wygenerowaną maszynowo specyfikację: mówi ona, co jest źle, gdzie i czego system oczekiwał zamiast tego. Pętla polega na wprowadzeniu zmiany, uruchomieniu weryfikacji, przekazaniu agentowi pierwszego błędu z docelowym kontekstem i naprawieniu jego przyczyny źródłowej.
CI świeci na czerwono. Czternaście błędów TypeScript, trzy nieudane testy i ostrzeżenie o deprecjacji. Stack trace wskazuje na payment.ts:212, spaliłeś już dwadzieścia minut na zgadywaniu, który z ostatnich sześciu commitów to zepsuł, a poprawka, którą właśnie wypchnąłeś, zamieniła jeden nieprzechodzący test w trzy. Wpatrywanie się w błąd mocniej nie działa.
Oba instynkty, które się teraz odzywają, są złe. Naprawianie wszystkiego ręcznie ignoruje to, w czym agent jest naprawdę dobry. Wklejenie całego loga z dopiskiem „napraw wszystko” daje mu zbyt wiele naraz i produkuje kaskadowe „naprawy”, które wprowadzają nowe problemy.
Komunikat błędu to najprecyzyjniejsza specyfikacja tego, co jest nie tak, jaką masz — i dokładnie ten rodzaj wejścia, który asystent AI konsumuje najlepiej, lepszy niż jakikolwiek prompt napisany od zera. Programowanie sterowane błędami to wykorzystuje: zamiast celować w idealny pierwszy szkic, uruchamiasz ciasną pętlę błąd → naprawa → restart i pozwalasz każdej awarii sterować kolejną zmianą. Robione świadomie, zbiega szybko nawet na paskudnych kaskadach.
Co daje programowanie sterowane błędami
Dział zatytułowany „Co daje programowanie sterowane błędami”- Powtarzalną pętlę błąd-naprawa-restart, którą uruchomisz w każdym z trzech narzędzi
- Gotowe prompty na produkcyjny stack trace, kaskadę kompilatora i pętlę z nieprzechodzącym testem
- Mechanikę każdego narzędzia: kto uruchamia testy, kto cofa złą poprawkę, kto iteruje bez nadzoru
- Wyjście awaryjne, gdy naprawienie jednego błędu wciąż produkuje trzy kolejne
- Skrót przez MCP, który pobiera zgłoszenie z Sentry zamiast kopiowania stack trace’ów
- Nawyk zamiany trudno wywalczonej poprawki w regułę w
CLAUDE.md,.cursor/rulesalboAGENTS.md
Pętla błąd-naprawa-restart
Dział zatytułowany „Pętla błąd-naprawa-restart”Zamiast próbować zapobiec wszystkim błędom, oprzyj się na nich jako najszybszym dostępnym mechanizmie sprzężenia zwrotnego:
- Wprowadź zmianę (lub pozwól agentowi ją wprowadzić)
- Uruchom krok weryfikacji (build, test, lint, type-check)
- Przeczytaj pierwszy błąd
- Przekaż go agentowi z docelowym kontekstem
- Pozwól agentowi naprawić przyczynę źródłową
- Powtórz od kroku 2
Kluczowa dyscyplina to jeden błąd na raz. Komunikaty błędów kaskadują: jedna przyczyna źródłowa produkuje dziesiątki dalszych błędów, a naprawienie pierwszego zwykle sprawia, że połowa pozostałych znika. Naprawianie błędu numer czternaście, gdy numer jeden wciąż tam jest, to zmarnowana praca.
Przekazywanie błędu każdemu z narzędzi
Dział zatytułowany „Przekazywanie błędu każdemu z narzędzi”Cykl jest wszędzie identyczny — ujawnij błąd, daj agentowi dość kontekstu, zastosuj poprawkę, uruchom ponownie dokładnie to, co zawiodło. Różni się to, kto uruchamia polecenie i jak wycofujesz złą poprawkę.
W trybie agenta Cursor sam uruchamia testy albo build, czyta wyjście terminala i iteruje bez kopiowania przez ciebie — po nieudanym poleceniu możesz po prostu powiedzieć „fix the error in the terminal”. Siatką bezpieczeństwa są punkty kontrolne: każda edycja agenta to punkt przywracania, więc gdy poprawka pogarsza sprawę, wracasz jednym kliknięciem do ostatniego zielonego stanu, zamiast to rozplątywać.
Gdy już wklejasz błąd, wklej go z kontekstem, który czyni go wykonalnym:
I ran npm run type-check and got this error:
src/services/notification.ts:42:5 - error TS2345:Argument of type 'string' is not assignable to parameterof type 'NotificationPayload'.
Fix the root cause. The function signature in @src/services/notification.tsexpects a NotificationPayload object, not a raw string. Check the callerat line 42 and the type definition in @src/types/notification.ts.Najlepsze, gdy chcesz obserwować pętlę i wtrącić się w momencie, gdy zacznie zbaczać.
Claude Code uruchamia kompilator i testy przez narzędzie Bash i podaje wyjście z powrotem sobie, więc pętla domyka się wewnątrz jednej sesji:
Run npm run type-check. For each error:1. Read the file and line number referenced in the error2. Understand the root cause (don't just suppress the error)3. Fix the root cause4. Re-run type-check to verify the fix5. Move to the next error
Fix errors one at a time. Do not batch fixes.Możesz też przepuścić wyjście prosto na wejście:
npm run type-check 2>&1 | claude -p "Fix the first TypeScript error. Show me the root cause and your fix."W trybie headless (claude -p) pętla może iterować na nieprzechodzącym poleceniu z limitem tur, żeby nie kręciła się w nieskończoność. Najlepsze, gdy pętla ma działać z terminala albo w CI — skryptowo i z ograniczeniem.
Codex uruchamia polecenia wewnątrz sandboxa. Do interaktywnej pętli użyj codex --sandbox workspace-write -c approval_policy=on-request: sandbox przepuszcza rutynowe edycje i polecenia testowe, a on-request to osobna polityka eskalacji, a nie hook na awarie — więc poproś Codeksa w prompcie, żeby zatrzymał się i zdał raport po określonej liczbie nieudanych prób.
Run npm run type-check. Fix each error one at a time,starting with the first one. After fixing each error,re-run the check to see if downstream errors resolved.Do not batch fixes -- address one root cause per iteration.W ChatGPT desktop możesz wkleić wyjście terminala wprost jako kontekst, a przy awariach CI integracja z GitHubem czyta wyjście nieudanego checku prosto z PR-a. Najlepsze, gdy chcesz, by przemielił długą listę błędów głównie bez nadzoru, ale zatrzymał się na prawdziwych awariach.
Pętla w trzech prawdziwych sytuacjach
Dział zatytułowany „Pętla w trzech prawdziwych sytuacjach”Błąd produkcyjny ze stack trace’u
Dział zatytułowany „Błąd produkcyjny ze stack trace’u”Użytkownik trafił na crash, a twój error tracker przechwycił wyjątek. Najszybsza droga to podać agentowi trace razem z plikami, które wskazuje — pełny wyjątek i stos, nie samą górną linię, bo górna ramka to miejsce, w którym wartość została odczytana, a rzadko to, w którym coś poszło źle.
Poprawka powinna sięgnąć tam, gdzie total stało się undefined — na przykład do koszyka bez pozycji wyżej w przepływie — a nie dokleić ?. w linii 212. Uruchom ponownie nieudaną ścieżkę; jeśli wypłynie nowy błąd, podaj go z powrotem i powtórz.
Kaskada kompilatora po refaktoryzacji
Dział zatytułowany „Kaskada kompilatora po refaktoryzacji”Zmieniłeś sygnaturę kluczowej funkcji i type-checker zapalił się trzydziestoma błędami w całej bazie kodu. To słodki punkt tej pętli, bo błędy są dokładną, wygenerowaną maszynowo listą roboczą. Nie naprawiaj najpierw niczego ręcznie; pozwól liście się zmaterializować, a potem oddaj całość.
Agent poprawia miejsca wywołań, uruchamia ponownie type-checker i powtarza. Godzina mordęgi ręcznej kończy się w kilku cyklach, bo agentowi nigdy nie nudzi się przy dwudziestym siódmym miejscu wywołania.
Nieprzechodzący test jako wyrocznia
Dział zatytułowany „Nieprzechodzący test jako wyrocznia”Najmocniejsza forma tej pętli to napisanie nieprzechodzącego testu na początku i pozwolenie agentowi, by sam doprowadził się do zieleni. Test jest jednoznaczną wyrocznią, więc pętla kończy się sama.
To ostatnie zdanie ma znaczenie. Bez niego nadgorliwy agent czasem „naprawi” awarię, rozluźniając asercję. Przypnij test jako specyfikację.
Przerwanie kaskady, która nie zbiega
Dział zatytułowany „Przerwanie kaskady, która nie zbiega”Lista robocza kompilatora kurczy się w miarę pracy. Groźny rodzaj kaskady robi odwrotnie: agent naprawia błąd 1, co wprowadza błąd 2, którego naprawa wprowadza błąd 3, a ty spalasz okno kontekstu na grę w kreta. Sygnałem jest ten sam plik pojawiający się w każdej rundzie. Gdy tak się dzieje, przestań naprawiać błędy i zabierz się za strukturę.
Gdy ten sam plik wraca raz za razem, odsuń kamerę:
We've been fixing errors in notification.ts for three iterationsand new ones keep appearing. Stop fixing individual errors.
Instead:1. Read the full file @src/services/notification.ts2. Read the types it depends on @src/types/notification.ts3. Read the test file @src/services/__tests__/notification.test.ts4. Identify the structural problem causing the cascade5. Propose a fix for the root architectural issue
Do not modify any files until I approve the approach.Użyj /clear, żeby zresetować kontekst, gdy wpadniesz w pętlę, a potem zacznij od szerszego spojrzenia:
I've been fixing TypeScript errors in src/services/notification.tsbut they keep cascading. Take a step back:
1. Read the file and all its imports2. Run npm run type-check and capture ALL errors related to this file3. Identify the common root cause4. Fix the structural issue rather than individual symptoms5. Re-run type-check to verifyPo więcej niż dwóch cyklach korekty na tym samym błędzie kontekst jest zanieczyszczony nieudanymi podejściami. /clear plus świeży prompt prawie zawsze zbiegnie szybciej niż brnięcie dalej.
Zacznij nowy wątek, gdy błędy kaskadują. Czysty kontekst pomaga Codeksowi zobaczyć problem strukturalny:
The file src/services/notification.ts has cascading TypeScript errors.Individual fixes keep introducing new errors.
Read the file and all its dependencies. Identify the structuralroot cause and fix it holistically. Run type-check after yourchanges to verify all errors are resolved.Zamiana błędów w trwałą wiedzę
Dział zatytułowany „Zamiana błędów w trwałą wiedzę”Najcenniejsze błędy to te, których nigdy więcej nie zobaczysz. Gdy błąd okazuje się nieoczywisty, zapisz lekcję w konfiguracji projektu, żeby agent unikał tej samej pomyłki w każdej kolejnej sesji.
Dodaj regułę projektu w .cursor/rules/errors.md:
---description: "Common errors and their fixes for this project"alwaysApply: true---
## Known Error Patterns
- When modifying notification types, always update both `src/types/notification.ts` AND the Zod schema in `src/validators/notification.ts`. They must stay in sync.- Redis connection errors in tests: run `docker compose up -d redis` before running the test suite.Dodaj lekcję do swojego CLAUDE.md albo poproś Claude, żeby ją zapamiętał:
Remember: when modifying notification types, always update bothsrc/types/notification.ts AND the Zod schema insrc/validators/notification.ts. They must stay in sync.Auto-pamięć Claude zapisze to w ~/.claude/projects/<project>/memory/ i wczyta w kolejnych sesjach. Umieszczenie tego zamiast w projektowym CLAUDE.md daje ten sam zysk całemu zespołowi.
Dodaj lekcję do swojego AGENTS.md:
## Known Error Patterns
- Notification types: always update both src/types/notification.ts AND the Zod schema in src/validators/notification.ts together.- Redis must be running for integration tests: docker compose up -d redisCodex czyta AGENTS.md na starcie każdej sesji, więc wskazówka stosuje się automatycznie do całej przyszłej pracy.
Gdzie pętla błąd-naprawa-restart się psuje
Dział zatytułowany „Gdzie pętla błąd-naprawa-restart się psuje”- Gonienie za niewłaściwym błędem w kaskadzie. Pierwszy błąd często powoduje resztę. Powiedz agentowi, żeby naprawił najwcześniejszy, źródłowy błąd i uruchomił ponownie, zanim ruszy pozostałe.
- Naprawianie objawu, nie przyczyny. Owinięcie dostępu do
undefinedw?.zatrzymuje crash, ale nie wyjaśnia, czemu wartości brakowało. Pytaj „gdzie to stało się undefined?”, a nie „zatrzymaj wyrzucenie”. - Agent tłumi zamiast naprawiać.
@ts-ignore,as any, puste bloki catch ieslint-disablew wyjściu oznaczają zarządzanie objawami. Bądź bezpośredni: nie tłum błędów, napraw przyczynę. - Wieczna pętla na niestabilnym teście. Niedeterministyczna awaria pozwala agentowi „naprawić”, uruchomić ponownie, zobaczyć zieleń i ogłosić zwycięstwo — a potem znów sypie się w CI. Najpierw zakwarantannij niestabilny test; nie uruchamiaj na nim tej pętli.
- Furtka edycji testu. Agenci czasem przepuszczają niezdaną asercję, osłabiając ją. Dodaj „do not modify the test” do każdego promptu sterowanego testami.
- Ślepota kontekstowa. Wklejenie samej górnej ramki stosu ukrywa prawdziwego winowajcę głębiej w trace’ie. Daj pełny trace i nazwij podejrzane pliki.
- Zbyt wiele błędów do przetworzenia. Gdy type-checker produkuje 200+ błędów, nie podawaj ich wszystkich. Przerób pierwsze trzy do pięciu — to zwykle przyczyny źródłowe — a potem uruchom ponownie i sprawdź, ile zostało.
- Komunikat błędu jest naprawdę nieprzejrzysty. Segfaulty i generyczne „internal server error” nie niosą żadnej specyfikacji. Przełącz się z podejścia sterowanego błędami na sterowane hipotezami: dodaj logowanie, odtwórz problem, zawężaj przez eliminację.
- Błąd jest w wygenerowanym kodzie. Gdy zepsuty plik to ten, który agent napisał od zera, usunięcie go i wygenerowanie ponownie z bardziej ograniczonego promptu zwykle bije łatanie.