07 - Debugowanie za pomocą kursora AI: 3x szybciej
Debugowanie to jedna z najbardziej czasochłonnych czynności w życiu programisty. Studia wewnętrzne Microsoft i Google podają, że starsi programiści wydają od 30 do 40 proc swój produktywny czas na wyszukiwanie i naprawianie błędów. Wraz z pojawieniem się IDE natywnych dla sztucznej inteligencji, to procent spada. Ci, którzy używają Cursora ze zoptymalizowanym przepływem pracy, zgłaszają aż do obniżek do 65 procent czasu spędzonego na debugowaniu, nie dlatego, że sztuczna inteligencja jest nieomylna, ale dlatego, że przekształca samotny i często frustrujący proces w zorganizowaną i systematyczną współpracę.
W tym artykule nie tylko dowiesz się, jak „poprosić sztuczną inteligencję o naprawienie błędu”. Zbadajmy specyficzne funkcje Cursora przeznaczone do debugowania, z Wprowadzono tryb debugowania z Kursorem 2.2 do systemu Buboty do proaktywnego przeglądu PR, przechodząc przez zaawansowane strategie dotyczące wycieków pamięci, warunków wyścigowych i niestabilnych testów w TypeScript i Angularowy. Dowiesz się, jak zbudować powtarzalny przepływ pracy, który zmieni debugowanie ze sztuki przesłania możliwy do sprawdzenia proces inżynieryjny.
Czego dowiesz się w tym artykule
- Jak działa tryb debugowania Cursora 2.2 i jego pętla agenta oparta na dziennikach wykonawczych
- Bugbot: Proaktywne wykrywanie błędów w żądaniach ściągnięcia z automatyczną naprawą
- Przepływ pracy Cmd+K i wbudowany czat do natychmiastowej analizy śledzenia stosu
- Skonfiguruj debuger TypeScript/Angular z mapami źródłowymi w Cursor
- Strategie sztucznej inteligencji dotyczące wycieków pamięci, warunków wyścigowych i niestabilnych testów
- Integracja z Chrome DevTools i natywnym debugerem VS Code
- Pełny cykl: odtwórz - wyizoluj - oprzyrząduj - napraw - zweryfikuj
- Porównanie debugowania tradycyjnego i wspomaganego sztuczną inteligencją z rzeczywistymi wskaźnikami
Artykuły z serii Cursor IDE i AI-Native Development
| # | Przedmiot | Poziom |
|---|---|---|
| 1 | Cursor IDE: Kompletny przewodnik dla programistów | Początkujący |
| 2 | Reguły kursora: konfigurowanie sztucznej inteligencji dla twojego projektu | Mediator |
| 3 | Tryb agenta: zmodyfikuj bazę kodu za pomocą polecenia | Mediator |
| 4 | Tryb planu i agenci działający w tle | Zaawansowany |
| 5 | Zaczepy kursora: automatyzuj przepływ pracy | Mediator |
| 6 | MCP i kursor: Połącz IDE z bazą danych i API | Zaawansowany |
| 7 | Jesteś tutaj - Debugowanie za pomocą kursora AI: 3x szybciej | Mediator |
| 8 | Kursor vs Windsurf vs Copilot w 2026 roku | Początkujący |
| 9 | Profesjonalny przebieg pracy: kątowy z kursorem | Zaawansowany |
Problem z tradycyjnym debugowaniem
Każdy, kto spędził trzy godziny wpatrując się w zapis stosu, aby dowiedzieć się, na czym polega problem
a undefined na polu dopuszczającym wartość null wie dokładnie, o czym mówimy. Debugowanie
tradycyjna metoda ma ogromny koszt poznawczy: trzeba zachować w głowie stan programu,
twórz hipotezy, dodawaj logi, odtwarzaj błąd, interpretuj wyniki i iteruj.
Każda przerwa w przepływie – nowy dziennik do dodania, punkt przerwania do przeniesienia –
zakłóca koncentrację.
Programiści używający Cursora do debugowania nie eliminują tego procesu, ale go przyspieszają radykalnie. Kluczem jest to, że sztuczna inteligencja może jednocześnie uwzględniać cały kontekst bazy kodu, skupiając się na logice wysokiego poziomu. Kursor 2.2 sformalizowany takie podejście z Tryb debugowania, zbudowano całkowicie nową pętlę agenta wokół informacji o czasie wykonywania i weryfikacji przez człowieka.
Debugowanie tradycyjne a debugowanie wspomagane sztuczną inteligencją: liczby
| Działalność | Tradycyjny | Z kursorem AI | Oszczędności |
|---|---|---|---|
| Analiza śladu stosu | 15-30 minut | 2-5 minut | ~80% |
| Identyfikacja przyczyny źródłowej | 1-4 godziny | 20-45 minut | ~70% |
| Napraw i sprawdź | 30-90 minut | 10-25 minut | ~65% |
| Badanie wycieku pamięci | 2-6 godzin | 45-90 minut | ~70% |
| Wykrywanie warunków wyścigu | 4-12 godzin | 1-3 godziny | ~75% |
| Niestabilna stabilizacja testu | 2-8 godzin | 30-60 minut | ~80% |
Tryb debugowania: pętla agenta Cursor 2.2
10 grudnia 2025 roku Cursor wydał wersję 2.2 wprowadzającą Tryb debugowania, jedna z najważniejszych funkcji w historii IDE. To nie jest proste Integracja debugera VS Code z AI: i całkowicie przeprojektowana pętla agentów wokół informacji wykonawczych i współpracy międzyludzkiej.
Jak działa pętla debugowania
Podstawowa różnica w porównaniu do ogólnego debugowania wspomaganego polega na tym, że tryb debugowania go nie szuka natychmiast, aby wygenerować poprawkę. Zamiast tego następuje pięcioetapowy proces:
Pętla trybu debugowania
- Analiza hipotetyczna: Kursor odczytuje bazę kodu i generuje wiele hipotez o tym, co może być nie tak, bez zakładania, że znamy przyczynę
- Oprzyrządowanie: Agent dodaje w punktach ukierunkowane dzienniki środowiska wykonawczego zidentyfikowane jako prawdopodobne źródła problemu
- Odtwarzanie z przewodnikiem: Kursor prosi użytkownika o odtworzenie błędu z zainstalowanym oprzyrządowaniem i gromadzi dane dotyczące czasu działania
- Ukierunkowana poprawka: Na podstawie rzeczywistych danych proponuje minimalną poprawkę i precyzyjne, zamiast spekulatywnego przepisywania
- Sprawdzanie i czyszczenie: Po sprawdzeniu usuń cały sprzęt pozostawiając czystą różnicę gotową do zatwierdzenia
Aby aktywować tryb debugowania, otwórz panel Kompozytor i kliknij menu obok przycisku wejdź i wybierz „Tryb debugowania”. Od tego momentu agent będzie działał w tej pętli zamiast bezpośrednio przystąpić do zmian.
// Esempio di come Cursor strumenta il codice durante Debug Mode
// File: src/app/services/payment.service.ts
// PRIMA della strumentazione
async processPayment(order: Order): Promise<PaymentResult> {
const cart = await this.cartService.getCart(order.userId);
const total = this.calculateTotal(cart);
return this.paymentGateway.charge(order.paymentMethod, total);
}
// DOPO la strumentazione aggiunta da Cursor Debug Mode
async processPayment(order: Order): Promise<PaymentResult> {
console.log('[DEBUG:cursor] processPayment called', {
orderId: order.id,
userId: order.userId,
paymentMethod: order.paymentMethod
});
const cart = await this.cartService.getCart(order.userId);
console.log('[DEBUG:cursor] cart retrieved', {
cartId: cart?.id,
itemCount: cart?.items?.length,
cartIsNull: cart === null
});
const total = this.calculateTotal(cart);
console.log('[DEBUG:cursor] total calculated', { total, cartTotal: cart?.total });
const result = await this.paymentGateway.charge(order.paymentMethod, total);
console.log('[DEBUG:cursor] payment result', { success: result.success, error: result.error });
return result;
}
// Dopo la riproduzione, Cursor vede nei log:
// [DEBUG:cursor] cart retrieved { cartId: undefined, itemCount: undefined, cartIsNull: false }
// Questo rivela che cart esiste ma items e undefined - bug trovato!
Podejście oparte na oprzyrządowaniu jest skoncentrowane i skuteczne, ponieważ eliminuje zgadywanie. Zamiast przepisz kod w oparciu o hipotezy, Cursor zbiera konkretne dowody przed podjęciem działań. Ostatecznym rezultatem jest zawsze minimalna różnica: tylko niezbędna poprawka, bez refaktoryzacji wymagane lub dodanie funkcji, które nie zostały uzgodnione.
Kiedy tryb debugowania jest najbardziej efektywny
- Sporadyczne błędy, które nie zawsze się powtarzają (warunki wyścigu, problemy z synchronizacją)
- Problemy w starszym kodzie, których nie znasz
- Błędy, które pojawiają się tylko w środowisku produkcyjnym z prawdziwymi danymi
- Błędy związane ze śledzeniem głębokiego stosu obejmującego wiele bibliotek
- Nieoczekiwane zachowania bez wyraźnych błędów (ciche awarie)
Tryb debugowania i mniej przydatny w przypadku oczywistych błędów kompilacji lub błędów TypeScriptu, gdzie inline Cmd+K jest znacznie szybsze.
Bugbot: Proaktywne wykrywanie błędów w PR
Podczas gdy tryb debugowania naprawia błędy po ich pojawieniu się, Buboty spróbuj przechwycić je, zanim w ogóle dotrą do produkcji. Wydany w wersji 1 w lipcu 2025 r i znacznie udoskonalony za pomocą Bugbota v11 w styczniu 2026 r., integruje się z procesem przeglądów kodu poprzez automatyczną analizę każdego żądania ściągnięcia.
Jak działa Bugbot
Bugbot analizuje różnicę PR przy użyciu wielu równoległych przebiegów, każdy z określoną kolejnością różne zmiany, aby pobudzić różne rozumowanie w modelu. Przychodzą rezultaty w połączeniu z głosowaniem większościowym w celu ograniczenia liczby fałszywych alarmów. Podejście to, podobne do a Wykazano, że zespół recenzentów-ludzi wyłapuje prawdziwe błędy, które pozostają niezauważone w tradycyjnych recenzjach kodu.
// Esempio di configurazione Bugbot rules in .cursor/bugbot.rules
// Queste regole personalizzano cosa Bugbot considera un bug nel tuo progetto
# Regole per progetto Angular/TypeScript
## Patterns Pericolosi
- Flag qualsiasi uso di 'any' in funzioni pubbliche dei servizi
- Segnala operatori non-null assertion '!' su proprietà di input Angular
- Evidenzia subscribe() senza corrispondente unsubscribe() o takeUntilDestroyed()
- Avvisa quando una migration SQL non ha rollback corrispondente
## Invarianti del Progetto
- I componenti non devono accedere direttamente all'HttpClient, solo ai servizi
- Tutti i form devono avere validazione lato client E lato server
- Non usare localStorage direttamente, usa StorageService
## Falsi Positivi da Ignorare
- I file *.spec.ts possono usare 'any' per i mock
- I file di configurazione possono avere assert non-null
Automatyczna naprawa błędów: automatyczna naprawa
Najpotężniejsza funkcja Bugbota v11 e Autopoprawka: kiedy Bugbot zidentyfikuje błąd w PR może automatycznie otworzyć agenta Cloud w celu wdrożenia poprawki. Agent proponuje zmiany jako komentarz do PR lub jako dodatkowe zatwierdzenie, o ile pozwala recenzentowi zaakceptowanie lub odrzucenie poprawki jednym kliknięciem.
// Bug trovato da Bugbot su PR #142:
// File: src/app/components/user-profile/user-profile.component.ts
// PROBLEMA: Memory leak - Observable non viene unsubscribed
@Component({
selector: 'app-user-profile',
template: `<div>{{ user?.name }}</div>`
})
export class UserProfileComponent implements OnInit {
user: User | null = null;
constructor(private userService: UserService) {}
ngOnInit() {
// BUGBOT: Observable subscription senza unsubscribe
// Causa memory leak quando il componente viene distrutto
this.userService.getCurrentUser().subscribe(user => {
this.user = user;
});
}
}
// FIX PROPOSTO DA BUGBOT AUTOFIX:
@Component({
selector: 'app-user-profile',
template: `<div>{{ user?.name }}</div>`
})
export class UserProfileComponent {
private destroyRef = inject(DestroyRef);
user: User | null = null;
constructor(private userService: UserService) {
this.userService.getCurrentUser()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(user => {
this.user = user;
});
}
}
Bugbot stale się rozwija. Kursor eksperymentuje z wersją zawsze włączony który stale skanuje bazę kodu zamiast czekać na PR i następną główną wersję pozwoli Bugbotowi uruchomić kod, aby najpierw zweryfikować własne raporty o błędach aby je zgłosić.
Szybkie debugowanie za pomocą Cmd+K i czatu wbudowanego
W przypadku większości codziennych błędów tryb debugowania i Bugbot są potężnymi narzędziami, ale czasem oversize. Najszybszy sposób na naprawienie oczywistych błędów w Cursor e przez Cmd+K (edycja bezpośrednia) i Panel czatu.
Natychmiastowa analiza śledzenia stosu
Gdy w konsoli lub terminalu pojawi się wyjątek, najbardziej efektywnym przepływem pracy jest:
- Wybierz cały ślad stosu w konsoli
- Naciskać
Cmd+Shift+L, aby dodać wybór do kontekstu czatu - Piszesz: „Przeanalizuj ślad stosu i zidentyfikuj pierwotną przyczynę. Pokaż, gdzie w kodzie leży problem i zaproponuj minimalne rozwiązanie.”
Kursor nie czyta tylko pierwszej linii błędu. Podąża ścieżkami plików na stosie, pobierz odpowiedni kod ze swojego projektu i zrekonstruuj mentalnie łańcuch połączeń co spowodowało wyjątek.
// Stack trace reale di un'app Angular con NgRx
ERROR TypeError: Cannot read properties of undefined (reading 'items')
at CartComponent.getItemCount (cart.component.ts:47:35)
at CartComponent_Template (cart.component.html:12:18)
at executeTemplate (core.mjs:11223)
at refreshView (core.mjs:11094)
at refreshComponent (core.mjs:12147)
at refreshChildComponents (core.mjs:11060)
// Cosa chiedi a Cursor:
// "Questo stack trace viene da un'app Angular con NgRx.
// CartComponent.getItemCount accede a items su una proprietà
// che risulta undefined. Analizza cart.component.ts e lo store
// corrispondente per trovare dove il dato non viene inizializzato."
// Cursor risponde analizzando:
// 1. cart.component.ts - come viene acceduto lo store
// 2. cart.reducer.ts - lo stato iniziale del reducer
// 3. cart.selectors.ts - i selettori usati nel componente
// E identifica:
// PROBLEMA in cart.reducer.ts:
const initialState: CartState = {
// 'items' manca! Lo stato iniziale non ha la proprietà
loading: false,
error: null
// items: [] <-- questa riga manca
};
// FIX:
const initialState: CartState = {
items: [], // aggiunto
loading: false,
error: null
};
Cmd+K dla kontekstowych poprawek wbudowanych
Kiedy już zidentyfikowałeś problematyczną linię, Cmd+K i o wiele więcej szybkie zastosowanie poprawki. Wybierz problematyczny kod, naciśnij Cmd+K i opisz problem w języku naturalnym. Kursor modyfikuje jedynie wybrany kod, bez kliknij pozostałą część pliku.
// Selezioni questo codice in un service Angular e premi Cmd+K:
getUserData(id: string) {
return this.http.get(`/api/users/${id}`);
}
// Scrivi: "aggiungi gestione errori, tipizzazione forte con User interface,
// e timeout di 5 secondi"
// Cursor genera:
getUserData(id: string): Observable<User> {
return this.http.get<User>(`/api/users/${id}`).pipe(
timeout(5000),
catchError((error: HttpErrorResponse) => {
if (error.status === 404) {
return throwError(() => new Error(`User ${id} not found`));
}
if (error.name === 'TimeoutError') {
return throwError(() => new Error('Request timed out'));
}
return throwError(() => new Error('Failed to load user data'));
})
);
}
Punkty kontrolne i wycofywanie podczas debugowania
Często pomijana funkcja podczas debugowania i systemu Punkty kontrolne Kursora. Podczas eksplorowania wielu hipotez dotyczących naprawy można zapisać bieżący stan bazy kodu jako punktu kontrolnego i wycofania, jeśli próba pogorszy sytuację.
Przepływ pracy z Checkpointem
- Zanim zaczniesz debugować złożony błąd, zapisz punkt kontrolny
- Wypróbuj pierwszą hipotezę naprawy za pomocą Kursora
- Uruchom testy: jeśli się nie powiodą, zresetuj punkt kontrolny jednym kliknięciem
- Przetestuj drugą hipotezę, zaczynając od stanu czystego
- Kontynuuj, aż testy zakończą się sukcesem
Eliminuje to klasyczny problem „pogorszyłem sytuację i nie wiem, jak wrócić”. dzięki czemu odkrywanie rozwiązań jest znacznie mniej ryzykowne.
Skonfiguruj debuger TypeScript/Angular w kursorze
Cursor używa tego samego silnika debugowania co VS Code, co oznacza, że wszystkie
launch.json wiesz, że działają identycznie. Różnica polega na tym, że kursor
dodaje warstwę sztucznej inteligencji do całego procesu, aby pomóc Ci zinterpretować to, co się dzieje
i szybciej rozwiązuj problemy.
Skonfiguruj mapy źródłowe dla TypeScript
Kluczowym wymogiem skutecznego debugowania TypeScriptu jest poprawna konfiguracja map źródłowych. Bez nich debuger wskazuje zamiast tego skompilowane pliki JavaScript niż do źródłowych plików TypeScript, co uniemożliwia odczytanie kodu podczas debugowania.
// tsconfig.json - configurazione base per debugging
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"sourceMap": true, // OBBLIGATORIO per debugging TS
"inlineSources": true, // Include sorgente nelle source maps
"inlineSourceMap": false, // Usa file .map separati
"outDir": "./dist",
"strict": true,
"moduleResolution": "node"
}
}
// .vscode/launch.json - configurazione per Angular con Chrome
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Angular App",
"type": "chrome",
"request": "launch",
"url": "http://localhost:4200",
"webRoot": "${workspaceFolder}/src",
"sourceMapPathOverrides": {
"webpack:///./src/*": "${webRoot}/*"
},
"skipFiles": [
"node_modules/**",
"**/*.spec.ts"
]
},
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": [
"--runInBand",
"--no-coverage",
"${file}"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "test"
}
},
{
"name": "Debug Node.js Server",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/server/index.ts",
"runtimeArgs": ["--require", "ts-node/register"],
"sourceMaps": true,
"envFile": "${workspaceFolder}/.env.local"
}
]
}
Po skonfigurowaniu launch.json, możesz uruchomić debuger F5
jak w VS Code. Różnica w przypadku kursora polega na tym, że można wybrać punkt przerwania lub liczbę całkowitą
funkcji w panelu debugowania i poproś sztuczną inteligencję o wyjaśnienie jej zachowania lub o
zasugerować, dlaczego zmienna ma nieoczekiwaną wartość.
Sztuczka: wyłącz natywny TypeScript kursora
W dużych projektach (monorepos, obszary robocze z ponad 100 modułami) serwer języka TypeScript Kursora może zużywać dużo pamięci. Jeśli zauważysz spowolnienie lub awarie, dodaj to konfiguracja do używania TypeScriptu twojego projektu zamiast wewnętrznego Cursora:
// .cursor/settings.json
{
"typescript.enableNativePreview": false,
"typescript.tsdk": "./node_modules/typescript/lib"
}
Wycieki pamięci, warunki wyścigowe i niestabilne testy z wykorzystaniem sztucznej inteligencji
Te trzy kategorie błędów są historycznie najtrudniejsze do debugowania, ponieważ nie są deterministyczne. Występują sporadycznie, często tylko w produkcji lub pod obciążeniem, a próby ich izolowania często je eliminują. AI kursora przynosi tutaj znaczącą zaletę: może analizować kod statycznie zidentyfikować wzory które prowadzą do tych błędów, nawet zanim się ujawnią.
Wycieki pamięci w Angular: diagnoza i naprawa
Najczęstszym wyciekiem pamięci w Angularze jest niezarządzana subskrypcja RxJS. Ale istnieją wiele innych problematycznych wzorców, które Cursor uczy się rozpoznawać w Twoim konkretnym projekcie.
// Prompt efficace per ricerca memory leak:
// "Analizza questo componente e identifica tutti i possibili
// memory leaks. Includi: subscriptions non gestite, event listeners
// non rimossi, interval/timeout non cancellati, e reference circolari."
// Componente con multipli leak:
@Component({
selector: 'app-dashboard',
template: `...`
})
export class DashboardComponent implements OnInit {
data: any[] = [];
private subscription: Subscription;
constructor(
private dataService: DataService,
private router: Router,
private renderer: Renderer2,
private elementRef: ElementRef
) {}
ngOnInit() {
// LEAK 1: Subscription senza unsubscribe
this.subscription = this.dataService.getStream()
.subscribe(data => this.data = data);
// LEAK 2: Event listener sul document non rimosso
document.addEventListener('keydown', this.handleKeyPress.bind(this));
// LEAK 3: Interval non cancellato
setInterval(() => this.refreshData(), 5000);
// LEAK 4: Router events subscription
this.router.events.subscribe(event => {
console.log(event);
});
}
handleKeyPress(event: KeyboardEvent) { /* ... */ }
refreshData() { /* ... */ }
}
// VERSIONE CORRETTA (generata da Cursor):
@Component({
selector: 'app-dashboard',
template: `...`
})
export class DashboardComponent implements OnInit, OnDestroy {
data: any[] = [];
private destroyRef = inject(DestroyRef);
private intervalId: ReturnType<typeof setInterval> | null = null;
private boundHandleKeyPress: (event: KeyboardEvent) => void;
constructor(
private dataService: DataService,
private router: Router
) {}
ngOnInit() {
// FIX 1: takeUntilDestroyed per tutte le subscriptions
this.dataService.getStream()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(data => this.data = data);
// FIX 2: Listener con cleanup esplicito
this.boundHandleKeyPress = this.handleKeyPress.bind(this);
document.addEventListener('keydown', this.boundHandleKeyPress);
// FIX 3: Interval con riferimento per cleanup
this.intervalId = setInterval(() => this.refreshData(), 5000);
// FIX 4: Router events con takeUntilDestroyed
this.router.events
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(event => console.log(event));
}
ngOnDestroy() {
document.removeEventListener('keydown', this.boundHandleKeyPress);
if (this.intervalId) {
clearInterval(this.intervalId);
}
}
handleKeyPress(event: KeyboardEvent) { /* ... */ }
refreshData() { /* ... */ }
}
Warunki wyścigu: wzór diagnozy
Warunki wyścigu w Angular często pojawiają się, gdy wiele asynchronicznych żądań HTTP kończą się w nieprzewidywalnej kolejności lub gdy stan komponentu jest aktualizowany po zniszczeniu komponentu.
// Race condition classica in Angular: richieste HTTP concorrenti
// L'utente digita velocemente nel search box - ogni keystroke
// lancia una nuova richiesta, ma non necessariamente arrivano in ordine
// PROBLEMA:
@Component({
selector: 'app-search',
template: `
<input (input)="onSearch($event)">
<div *ngFor="let result of results">{{ result.title }}</div>
`
})
export class SearchComponent {
results: SearchResult[] = [];
constructor(private searchService: SearchService) {}
onSearch(event: Event) {
const query = (event.target as HTMLInputElement).value;
// RACE CONDITION: se digiti "an" poi "ang", la risposta per "an"
// potrebbe arrivare DOPO quella per "ang", mostrando risultati sbagliati
this.searchService.search(query).subscribe(results => {
this.results = results;
});
}
}
// SOLUZIONE con switchMap (generata da Cursor):
@Component({
selector: 'app-search',
template: `
<input [formControl]="searchControl">
<div *ngFor="let result of results$ | async">{{ result.title }}</div>
`
})
export class SearchComponent {
searchControl = new FormControl('');
private destroyRef = inject(DestroyRef);
results$ = this.searchControl.valueChanges.pipe(
debounceTime(300), // Attendi 300ms dopo l'ultimo keystroke
distinctUntilChanged(), // Ignora se il valore non cambia
filter(query => (query?.length ?? 0) >= 2), // Min 2 caratteri
switchMap(query => // Cancella la richiesta precedente
this.searchService.search(query ?? '').pipe(
catchError(() => of([])) // Gestisce errori senza rompere lo stream
)
),
takeUntilDestroyed(this.destroyRef)
);
constructor(private searchService: SearchService) {}
}
Niestabilne testy: strategie stabilizacji
Jednym z problemów są niestabilne testy (testy, które okazjonalnie kończą się sukcesem i niepowodzeniem). najbardziej frustrujący współczesny rozwój. Kursor jest szczególnie skuteczny w identyfikacji przyczyny, ponieważ może jednocześnie analizować test, testowany kod i wzorce czasu.
// Flaky test in Angular: problema con async/await e timing
// Questo test fallisce circa il 30% delle volte
// FLAKY TEST:
it('should update user when form is submitted', fakeAsync(() => {
const fixture = TestBed.createComponent(UserFormComponent);
const component = fixture.componentInstance;
fixture.detectChanges();
component.nameControl.setValue('John Doe');
component.onSubmit();
// Problema: il test non aspetta il completamento dell'Observable
expect(component.successMessage).toBe('User updated successfully');
}));
// Cosa chiedi a Cursor:
// "Questo test e flaky - fallisce intermittentemente. Analizza il
// componente UserFormComponent e identifica perchè il test non e
// deterministico. Proponi una versione stabile del test."
// RISPOSTA DI CURSOR - analisi del problema:
// Il componente usa un Observable con delay, il test non lo aspetta correttamente
// TEST STABILE (generato da Cursor):
it('should update user when form is submitted', fakeAsync(() => {
const userServiceSpy = jasmine.createSpyObj('UserService', ['updateUser']);
userServiceSpy.updateUser.and.returnValue(of({ success: true }).pipe(delay(100)));
TestBed.configureTestingModule({
declarations: [UserFormComponent],
providers: [
{ provide: UserService, useValue: userServiceSpy }
]
});
const fixture = TestBed.createComponent(UserFormComponent);
const component = fixture.componentInstance;
fixture.detectChanges();
component.nameControl.setValue('John Doe');
component.onSubmit();
// Avanza il tempo virtuale di 100ms per completare il delay
tick(100);
fixture.detectChanges();
expect(component.successMessage).toBe('User updated successfully');
expect(userServiceSpy.updateUser).toHaveBeenCalledOnceWith({
name: 'John Doe'
});
}));
Profilowanie wydajności wspomagane przez sztuczną inteligencję
Debugowanie wydajnościowe to osobna dyscyplina: nie chodzi o znajdowanie błędów, ale o zrozumieć, dlaczego coś jest powolne. Kursor nie zastępuje dedykowanych profilerów, takich jak Chrome DevTools czy Angular DevTools, ale znacznie przyspiesza proces interpretacji profilowania danych i wdrażania optymalizacji.
Analizowanie profili wydajności za pomocą kursora
Najbardziej efektywny przepływ pracy i przechwytywanie danych dotyczących wydajności za pomocą natywnych narzędzi, a następnie przynieś wyniki w Kursorze do analizy i wdrożenia poprawek.
// Esempio di workflow: ottimizzare un componente Angular lento
// Hai identificato con Angular DevTools che questo componente
// causa 850ms di change detection su ogni input
// Componente problematico (dati dal profiler):
@Component({
selector: 'app-large-table',
template: `
<table>
<tr *ngFor="let item of processedItems">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ formatDate(item.createdAt) }}</td>
<td>{{ calculateTotal(item) }}</td>
</tr>
</table>
`
})
export class LargeTableComponent {
@Input() items: RawItem[] = [];
// PROBLEMA 1: getter ricalcolato ad ogni change detection
get processedItems() {
return this.items.map(item => this.processItem(item));
}
// PROBLEMA 2: funzione chiamata nel template - ricreata ogni volta
formatDate(date: Date): string {
return new Intl.DateTimeFormat('it-IT').format(date);
}
// PROBLEMA 3: calcolo costoso nel template
calculateTotal(item: RawItem): number {
return item.prices.reduce((acc, price) => acc + price.amount, 0);
}
private processItem(item: RawItem): ProcessedItem { /* ... */ }
}
// VERSIONE OTTIMIZZATA (generata da Cursor con spiegazione):
@Component({
selector: 'app-large-table',
template: `
<table>
<tr *ngFor="let item of processedItems; trackBy: trackById">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.formattedDate }}</td>
<td>{{ item.total }}</td>
</tr>
</table>
`,
changeDetection: ChangeDetectionStrategy.OnPush // FIX 3: OnPush CD
})
export class LargeTableComponent {
private _items: RawItem[] = [];
processedItems: ProcessedItem[] = [];
@Input() set items(value: RawItem[]) {
this._items = value;
// FIX 1: calcola solo quando input cambia, non ad ogni CD
this.processedItems = value.map(item => this.processItem(item));
}
// FIX 2: trackBy per evitare ricreazione DOM inutile
trackById(index: number, item: ProcessedItem): string {
return item.id;
}
private dateFormatter = new Intl.DateTimeFormat('it-IT');
private processItem(item: RawItem): ProcessedItem {
return {
...item,
// Pre-calcola tutto durante la trasformazione
formattedDate: this.dateFormatter.format(item.createdAt),
total: item.prices.reduce((acc, price) => acc + price.amount, 0)
};
}
}
Integracja z Chrome DevTools
W przypadku zaawansowanego debugowania wydajności najpotężniejszy przepływ pracy łączy narzędzia Chrome DevTools z Kursorem. Przechwyć profil wydajności lub pamięci w przeglądarce Chrome, wyeksportuj dane i poproś Cursora o zinterpretowanie ich w kontekście twojej bazy kodu.
// Workflow con Chrome DevTools + Cursor
// 1. In Chrome DevTools > Performance, cattura un profilo
// Identifica i frame lenti (rossi) e le funzioni costose
// 2. Copia il nome delle funzioni costose nel profile:
// "component_factory.ts:847 - ComponentFactory.create - 234ms"
// 3. Porta in Cursor:
// "Ho profilato la mia app Angular e component_factory.create
// richiede 234ms nei frame lenti. Il profiler mostra che viene
// chiamata quando l'utente cambia route. Analizza il sistema
// di routing e lazy loading e identifica dove i componenti
// vengono ricreati invece di essere riutilizzati."
// 4. Per heap snapshots (memory leaks):
// - In Chrome DevTools > Memory, prendi due heap snapshots:
// uno prima e uno dopo un'operazione sospetta
// - Confronta: Objects allocated between snapshots
// - Copia i tipi di oggetti con crescita anomala in Cursor:
// "Il heap snapshot mostra un aumento di 15MB in
// 'EventEmitter' instances dopo navigazione back/forward.
// Analizza i componenti che usano EventEmitter e identifica
// dove non vengono destroyati correttamente."
Przepływ pracy debugowania: odtwarzaj, izoluj, naprawiaj, testuj
Posiadanie pojedynczych, potężnych funkcji nie wystarczy. Prawdziwa przewaga konkurencyjna wynika z integracji tych narzędzi w powtarzalny i systematyczny sposób pracy. Oto przepływ pracy opracowany przez programistów bardziej produktywny dzięki ujednoliceniu kursora.
Krok 1: Graj z maksymalnym kontekstem
Zanim dotkniesz kodu, zbierz wszystkie dostępne informacje o błędzie. Z kursorem, oznacza to zapewnienie AI najbogatszego możliwego kontekstu.
// Template per il primo messaggio di debugging in Cursor Chat:
/*
BUG REPORT:
- Comportamento atteso: [descrizione]
- Comportamento osservato: [descrizione]
- Frequenza: [sempre / intermittente al X%]
- Ambiente: [dev / staging / prod]
- Ultima modifica correlata: [commit hash o feature]
ERROR OUTPUT:
[incolla lo stack trace completo]
PASSI PER RIPRODURRE:
1. [passo 1]
2. [passo 2]
FILES PROBABILMENTE COINVOLTI:
- src/app/services/order.service.ts
- src/app/components/checkout/checkout.component.ts
@codebase analizza i file rilevanti e proponi le prime 3 ipotesi
sulla root cause, ordinate per probabilità.
*/
Faza 2: Izolacja przy minimalnym teście
Po zidentyfikowaniu najbardziej prawdopodobnej hipotezy poproś Cursora o utworzenie testu który odtwarza błąd w izolacji. Ma to dwie zalety: Sprawdzenie hipotezy i zapewnia automatyczne testy regresyjne.
// Prompt per creare un test di isolamento:
// "Sulla base dell'analisi, il bug sembra essere in OrderService.calculateDiscount()
// quando items ha elementi con quantity: 0. Crea un unit test Jest che riproduce
// esattamente questo scenario e verifica il comportamento corretto."
// Cursor genera:
describe('OrderService.calculateDiscount', () => {
let service: OrderService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(OrderService);
});
// Test che riproduce il bug
it('should handle items with zero quantity without throwing', () => {
const orderWithZeroQty = {
items: [
{ id: '1', price: 100, quantity: 2 },
{ id: '2', price: 50, quantity: 0 }, // caso problematico
{ id: '3', price: 75, quantity: 1 }
],
discountCode: 'SAVE10'
};
// BUG: questo throw invece di restituire 0
expect(() => service.calculateDiscount(orderWithZeroQty)).not.toThrow();
expect(service.calculateDiscount(orderWithZeroQty)).toBe(17.5);
});
});
Faza 3: Napraw za pomocą weryfikacji przyrostowej
Po przeprowadzeniu testu izolacji zastosuj poprawkę i natychmiast sprawdź. Podejście odwrotne TDD – najpierw test regresji, potem naprawa – np szczególnie skuteczny w przypadku kursora, ponieważ można szybko iterować.
// Prompt per la fix:
// "Il test di isolamento conferma il bug. Il problema e in calculateDiscount
// quando quantity e 0 causa una divisione per zero nel calcolo del prezzo
// unitario medio. Fixa calculateDiscount gestendo il caso quantity === 0
// e assicurati che tutti i test esistenti continuino a passare."
// Cursor analizza e genera la fix:
calculateDiscount(order: Order): number {
const validItems = order.items.filter(item => item.quantity > 0); // FIX
if (validItems.length === 0) {
return 0;
}
const subtotal = validItems.reduce(
(sum, item) => sum + (item.price * item.quantity),
0
);
const discount = this.discountService.getDiscount(order.discountCode);
return subtotal * (discount / 100);
}
Faza 4: Pełny test regresji
Po naprawieniu poproś Cursora o wygenerowanie pełnego zestawu testów obejmujących błąd naprawione i powiązane przypadki Edge, aby upewnić się, że problem się nie powtórzy.
// Prompt finale:
// "La fix e applicata e il test di isolamento passa. Ora genera una suite
// completa di test per calculateDiscount che copre: items normali,
// items con quantity 0, lista vuota, discount code invalido,
// e ordini con tutti gli items a quantity 0."
// Cursor genera 8 test cases che coprono tutti gli edge cases
// e aggiunge JSDoc al metodo spiegando il comportamento atteso
Najlepsze praktyki dotyczące debugowania wspomaganego sztuczną inteligencją
1. Zawsze dokładny kontekst
Debugowanie wspomagane sztuczną inteligencją jest tak dobre, jak kontekst, który podasz. Różnica między niejasnym podpowiedzią a dokładną podpowiedzią może być różnicą między 10 minut i 2 godziny pracy.
Zasady skutecznego monitu o debugowanie
- Pełny ślad stosu: zawsze 5-10 linii, nie tylko pierwsza
- Oczekiwane a zaobserwowane zachowanie: wyjaśnia oba
- Kontekst pliku: USA
@filename.tsdołączyć odpowiednie pliki - Ostatnia modyfikacja: podaj zatwierdzenie lub funkcję, jeśli błąd pojawił się niedawno
- Środowisko: dev/staging/prod często zmienia zachowanie
- Częstotliwość: zawsze/przerywany/tylko pod obciążeniem
2. Nie ufaj ślepo Napraw sztuczną inteligencję
Sztuczna inteligencja może generować poprawki, które usuwają objawy, ale nie przyczynę. Prawidłowy przebieg pracy, np zawsze: zrozum proponowaną poprawkę, zweryfikuj ją testami i świadomie zatwierdź.
Anty-wzorzec: akceptowanie poprawek bez ich zrozumienia
Wzorzec „debugowania wibracji” - poproś sztuczną inteligencję o naprawienie błędu, zaakceptuj pierwszy propozycja bez jej zrozumienia, wepchnięcie do produkcji - to najszybszy sposób na akumulację dług techniczny. Każda poprawka musi być:
- Dzieje się to na poziomie logicznym
- Zweryfikowano co najmniej jednym testem
- Sprawdzony pod kątem niezamierzonych skutków ubocznych
3. Użyj reguł kursora do debugowania
Możesz skonfigurować reguły kursora specyficzne dla debugowania, które szkolą sztuczną inteligencję na wzorcach Twojego projektu, unikając poprawek naruszających Twoje konwencje.
// .cursor/rules/debugging.mdc
---
name: Debugging Standards
globs: ["src/**/*.ts", "src/**/*.spec.ts"]
---
# Standard di Debugging per Questo Progetto
## Quando proponi un fix per un bug:
1. Spiega la root cause in massimo 3 frasi
2. Mostra PRIMA il codice problematico con commento // PROBLEMA:
3. Mostra POI la versione corretta con commento // FIX:
4. Aggiungi un test di regressione per il caso problematico
## Pattern da evitare nei fix:
- Non usare 'any' come fix temporanea per errori TypeScript
- Non aggiungere try/catch senza gestione specifica dell'errore
- Non usare '!' (non-null assertion) per silenziare errori nullable
- Non modificare i test per farli passare invece di fixare il codice
## Pattern preferiti:
- Usa Optional Chaining (?.) per accessi nullable
- Usa Nullish Coalescing (??) per default values
- Usa type guards per narrowing
- Usa catchError con specifici tipi di errore in RxJS
4. Sesje debugowania jako dokumentacja
Zaawansowana najlepsza praktyka i traktuj sesje debugowania jako okazję do dokumentacja. Po naprawieniu złożonego błędu poproś Cursora o wygenerowanie komentarz wyjaśniający w kodzie, który dokumentuje znaleziony problem i jego przyczynę przyjęte rozwiązanie jest prawidłowe.
// Prompt post-fix:
// "Il bug e risolto. Aggiungi un commento JSDoc a calculateDiscount
// che documenta: il bug che abbiamo trovato (divisione per zero
// con quantity 0), la soluzione adottata (filter prima del calcolo),
// e un link al test di regressione."
// Cursor genera:
/**
* Calcola lo sconto totale per un ordine basato su un codice sconto.
*
* Nota: gli items con quantity === 0 vengono esclusi dal calcolo
* per evitare errori di divisione per zero nel calcolo del prezzo
* unitario medio. Questo comportamento e testato in:
* order.service.spec.ts > 'should handle items with zero quantity'
*
* @param order - L'ordine con items e codice sconto
* @returns Il valore dello sconto in euro (0 se nessun item valido)
*/
calculateDiscount(order: Order): number {
Narzędzia do debugowania i integracje
Integracja z Datadogiem
For teams using Datadog in production, the official Cursor extension allows you to wprowadzaj dane monitorowania produkcji bezpośrednio do IDE. Możesz dodać punkty logowania, przeglądając je w Kursorze i poproś agenta o pomoc rozwiązywać problemy w środowisku produkcyjnym w oparciu o rzeczywiste dzienniki i ślady.
Skonfiguruj Datadog + Kursor
- Zainstaluj rozszerzenie Datadog z Cursor Extensions (kompatybilne z VS Code)
- Skonfiguruj dane uwierzytelniające Datadog w ustawieniach
- W sesjach debugowania użyj
@datadogaby umieścić prawdziwe logi w kontekście - Poproś Cursora o powiązanie błędów produkcyjnych z kodem źródłowym
Angular DevTools i kursor
Angular DevTools w przeglądarce i doskonały profiler dla problemów specyficznych dla Angulara (wykrywanie zmian, drzewo komponentów, wstrzykiwanie zależności). Kiedy znajdziesz problem w profilerze przenieś informacje do Cursora w celu analizy kodu.
// Workflow Angular DevTools + Cursor
// 1. Apri Angular DevTools (F12 > Angular tab)
// 2. Profila la change detection: ogni barra rossa = frame lento
// 3. Clicca sul componente lento - vedi le proprietà e il tempo CD
// 4. In Cursor, porta il contesto:
// "Angular DevTools mostra che ProductListComponent impega 450ms
// per la change detection. Il profiler indica che il re-render
// avviene 47 volte in 1 secondo durante lo scroll.
// @product-list.component.ts analizza e ottimizza la change
// detection strategy e l'uso degli input."
// Cursor risponderà con:
// - Analisi del componente
// - Identificazione dei problemi (mancanza di OnPush, trackBy, ecc.)
// - Implementazione ottimizzata
Debugowanie tradycyjne a wspomagane sztuczną inteligencją: kiedy czego używać
Sztuczna inteligencja nie zastępuje wszystkich podejść do debugowania. Istnieją scenariusze, w których debugowanie tradycyjny podręcznik, a nawet lepszy lub uzupełniający.
Przewodnik: jakiego podejścia użyć
| Scenariusz | Zalecane podejście | Narzędzia |
|---|---|---|
| Błąd TypeScriptu/kompilacji | Wbudowane Cmd+K | Edycja wbudowana kursora |
| Śledzenie stosu z błędem wykonania | Czatuj z kontekstem pliku | Czat kursora + @plik |
| Sporadyczny błąd/wyścig | Tryb debugowania | Tryb debugowania kursora (2.2) |
| Postępujący wyciek pamięci | Profiler + analiza AI | Chrome DevTools + czat kursora |
| Regresja wydajności | Profiler + optymalizacja AI | Angular DevTools + Kursor |
| Błąd w nieznanym starszym kodzie | Tryb debugowania + @codebase | Tryb debugowania kursora + kontekst |
| Debugowanie sprzętowe/niskiego poziomu | Natywny debuger | gdb/lldb, ręczne punkty przerwania |
| Luki w zabezpieczeniach | Ręczny przegląd kodu | Kursor + ekspertyza od człowieka |
Wnioski: Budowanie kultury debugowania wspomaganego sztuczną inteligencją
Debugowanie za pomocą Cursor AI to nie tylko kwestia narzędzi, to zmiana mentalności. Najbardziej produktywni programiści nie „proszą sztucznej inteligencji o naprawienie błędów” – oni tworzą ustrukturyzowany dialog z AI, podanie precyzyjnego kontekstu, weryfikacja hipotez testami, i używanie odpowiednich narzędzi do każdego rodzaju problemu.
Tryb debugowania w Cursor 2.2 stanowi skok jakościowy: już nie musi ekspertów baz kodu w celu skutecznego debugowania. Podejście oparte na hipotezach z Oprzyrządowanie wykonawcze radykalnie skraca czas spędzony na domysłach. Bugbot się porusza część obciążenia związanego z wykrywaniem błędów w czasie przeglądu kodu, zmniejszając ich liczbę błędów, które docierają do produkcji.
Dla zespołów Angular zysk jest szczególnie znaczący w obszarach o znaczeniu historycznym trudniejsze: wycieki subskrypcji, warunki wyścigu w Observables, niestabilne testy asynchroniczne i skuteczność wykrywania zmian. Kursor zna te wzorce i rozpoznaje je szybko, co mniej doświadczonemu programiście mogłoby zająć wiele godzin.
Lista kontrolna dotycząca rozpoczęcia korzystania z debugowania wspomaganego sztuczną inteligencją
- Skonfiguruj
launch.jsonz włączonymi mapami źródłowymi - Umiejętność
sourceMap: trueneltsconfig.json - Utwórz reguły kursora dla standardów debugowania swojego projektu
- Przećwicz szablon „RAPORT O BŁĘDZIE” w monitach debugowania
- Eksperymentuj z trybem debugowania na prawdziwym błędzie w bazie kodu
- Skonfiguruj Bugbota, jeśli używasz żądań ściągnięcia (GitHub/GitLab)
- Zintegruj przepływ pracy: odtwórz - przetestuj - napraw - zweryfikuj za pomocą kursora
Kontynuacja serii Cursor IDE
Ukończyłeś artykuł dotyczący debugowania. Kontynuuj z innymi artykułami z tej serii:
- Następny artykuł: Kursor vs Windsurf vs Copilot w 2026 roku - pełne porównanie BIZ AI na obecnym rynku
- Aby uzyskać pełne przepływy pracy: Profesjonalny przebieg pracy: projekt kątowy z kursorem
- Aby zautomatyzować kontrole: Zaczepy kursora: automatyzuj przepływ pracy
Powiązane serie krzyżowe: MCP i kursor do debugowania z rzeczywistymi danymi z bazy danych i serią Nowoczesny kątowy dla konkretnych najlepszych praktyk Angular.







