07 - Depanare cu Cursor AI: de 3x mai rapid
Depanarea este una dintre activitățile care consumă cel mai mult timp din viața unui dezvoltator. Studii interne Microsoft și Google raportează că dezvoltatorii seniori cheltuiesc între 30 și 40 la sută din timpul lor productiv în căutarea și remedierea erorilor. Odată cu apariția IDE-urilor native AI, aceasta procentul se prăbușește. Cei care folosesc Cursor cu un flux de lucru optimizat raportează până la reduceri la 65% din timpul petrecut cu depanarea, nu pentru că AI este infailibilă, ci pentru că transformă un proces solitar și adesea frustrant într-o colaborare structurată și sistematică.
Acest articol nu vă arată doar cum să „cereți AI să remedieze o eroare”. Să explorăm caracteristicile specifice ale Cursorului dedicat depanării, de la A fost introdus modul de depanare cu Cursorul 2.2 la sistem Bugbots pentru revizuirea proactivă a PR-urilor, trecând prin strategii avansate privind scurgerile de memorie, condițiile de cursă și testele nesigure în TypeScript și unghiulară. Veți învăța să construiți un flux de lucru repetabil care transformă depanarea dintr-o artă ascunde un proces de inginerie verificabil.
Ce veți învăța în acest articol
- Cum funcționează modul de depanare al cursorului 2.2 și bucla de agent bazată pe jurnalele de rulare
- Bugbot: detectarea proactivă a erorilor la solicitările de extragere cu remediere automată
- Flux de lucru Cmd+K și chat inline pentru analiza instantanee a urmei stivei
- Configurați depanatorul TypeScript/Angular cu hărți sursă în Cursor
- Strategii de inteligență artificială pentru pierderile de memorie, condițiile de cursă și testele scazute
- Integrare cu Chrome DevTools și depanatorul nativ VS Code
- Ciclul complet: reproducere - izolare - instrumentare - reparare - verificare
- Comparație între depanarea tradițională și asistată de AI cu valori reale
Articole din seria Cursor IDE și AI-Native Development Series
| # | Articol | Nivel |
|---|---|---|
| 1 | Cursor IDE: Ghid complet pentru dezvoltatori | Începător |
| 2 | Reguli cursor: Configurarea AI pentru proiectul dvs | Intermediar |
| 3 | Modul agent: Modificați baza de cod cu o comandă | Intermediar |
| 4 | Modul Plan și agenți de fundal | Avansat |
| 5 | Cârlige de cursor: automatizează fluxul de lucru | Intermediar |
| 6 | MCP și Cursor: Conectați IDE la baza de date și la API | Avansat |
| 7 | Sunteți aici - Depanare cu Cursor AI: de trei ori mai rapid | Intermediar |
| 8 | Cursor vs Windsurf vs Copilot în 2026 | Începător |
| 9 | Flux de lucru profesional: unghiular cu cursor | Avansat |
Problema cu depanarea tradițională
Oricine a petrecut trei ore uitându-se la o urmă de stivă pentru a afla care era problema
a undefined pe un câmp null știe exact despre ce vorbim. Depanare
metoda tradițională are un cost cognitiv enorm: trebuie să ții în cap starea programului,
faceți ipoteze, adăugați jurnalele, reproduceți eroarea, interpretați rezultatele și repetați.
Fiecare întrerupere a fluxului - un jurnal nou de adăugat, un punct de întrerupere de mutat -
rupe concentrarea.
Dezvoltatorii care folosesc Cursor pentru depanare nu elimină acest proces, ci îl accelerează radical. Cheia este că AI poate ține cont de întregul context simultan a bazei de cod în timp ce vă concentrați pe logica de nivel înalt. Cursorul 2.2 formalizat această abordare cu Modul de depanare, o buclă de agent complet nouă construită în jurul informațiilor de rulare și verificării umane.
Depanare tradițională vs asistată de AI: numerele
| Activitate | Tradiţional | Cu Cursor AI | Economii |
|---|---|---|---|
| Analiza urmelor stivei | 15-30 min | 2-5 min | ~80% |
| Identificarea cauzei principale | 1-4 ore | 20-45 min | ~70% |
| Remediați și verificați | 30-90 min | 10-25 min | ~65% |
| Investigarea scurgerilor de memorie | 2-6 ore | 45-90 min | ~70% |
| Detectarea condiției de cursă | 4-12 ore | 1-3 ore | ~75% |
| Stabilizare test de fulgi | 2-8 ore | 30-60 min | ~80% |
Modul de depanare: bucla de agent Cursor 2.2
Pe 10 decembrie 2025, Cursor a lansat versiunea 2.2 introducând Modul de depanare, una dintre cele mai semnificative caracteristici din istoria IDE-ului. Nu este unul simplu Integrarea depanatorului VS Code cu AI: și o buclă de agent complet reproiectată în jurul informațiilor de rulare și a colaborării umane.
Cum funcționează bucla de depanare
Diferența fundamentală în comparație cu depanarea asistată generică este că Modul de depanare nu îl caută imediat pentru a genera o remediere. În schimb, urmează un proces în cinci pași:
Bucla modului de depanare
- Analiza ipotetică: Cursorul citește baza de cod și generează mai multe ipoteze despre ceea ce ar putea fi greșit, fără a presupune că știm cauza
- Instrumentaţie: Agentul adaugă jurnalele de rulare vizate în puncte identificate ca surse probabile ale problemei
- Redare ghidată: Cursorul cere utilizatorului să reproducă eroarea cu instrumentele la locul lor și colectează date de rulare
- Remediere vizată: Pe baza datelor reale, propune o remediere minimă şi precisă în loc de o rescriere speculativă
- Verificare și curățare: După verificare, scoateți toate echipamentele lăsând un difer curat pregătit pentru comitere
Pentru a activa modul Debug, deschideți panoul Composer, faceți clic pe meniul drop-down de lângă buton intrați și selectați „Modul de depanare”. Din acel moment, agentul va opera în această buclă în loc să procedeze direct cu modificările.
// 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!
Abordarea instrumentării este concentrată și puternică, deoarece elimină presupunerile. În loc de rescrie codul pe baza ipotezelor, Cursor colectează dovezi concrete înainte de a lua măsuri. Rezultatul final este întotdeauna o diferență minimă: doar reparația necesară, fără refactorizare solicitate sau adăugări de caracteristici care nu au fost convenite.
Când modul de depanare este cel mai eficient
- Erori intermitente care nu se reproduc întotdeauna (condiții de cursă, probleme de cronometrare)
- Probleme în codul moștenit cu care nu sunteți familiarizat
- Bug-uri care apar doar în producție cu date reale
- Erori cu urmărirea stivă profundă care acoperă mai multe biblioteci
- Comportamente neașteptate fără erori explicite (eșecuri silențioase)
Modul de depanare și mai puțin util pentru erori evidente de compilare sau erori TypeScript, unde Cmd+K inline este mult mai rapid.
Bugbot: Detectare proactivă a erorilor în PR
În timp ce Modul Depanare remediază erorile după ce apar, Bugbots incearca sa interceptați-le chiar înainte de a ajunge la producție. Lansat în versiunea 1 în iulie 2025 și îmbunătățit semnificativ cu Bugbot v11 în ianuarie 2026, se integrează în proces de recenzii de cod prin analiza automată a fiecărei cereri de extragere.
Cum funcționează Bugbot
Bugbot analizează diferența de PR folosind mai multe treceri paralele, fiecare cu o comandă diferite modificări pentru a stimula raționament diferit în model. Rezultatele vin combinate cu votul majoritar pentru a reduce falsele pozitive. Această abordare, similară cu a ansamblu de recenzenți umani, s-a dovedit că prinde bug-uri reale care trec neobservate în recenziile tradiționale de cod.
// 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
Bugbot Autofix: Remediere automată
Cea mai puternică caracteristică a Bugbot v11 e Remediere automată: când se identifică Bugbot o eroare într-un PR poate deschide automat un agent cloud pentru a implementa remedierea. Agentul propune modificările ca un comentariu la PR sau ca un comit suplimentar, permițând examinatorul să accepte sau să respingă remedierea cu un singur clic.
// 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 este în continuă evoluție. Cursorul experimentează cu o versiune mereu pornit care scanează continuu baza de cod în loc să aștepte PR-uri și următoarea lansare majoră va permite lui Bugbot să ruleze cod pentru a-și verifica mai întâi propriile rapoarte de eroare pentru a le raporta.
Depanare rapidă cu Cmd+K și chat inline
Pentru majoritatea erorilor de zi cu zi, Modul Depanare și Bugbot sunt instrumente puternice, dar uneori supradimensionate. Cel mai rapid mod de a remedia erori evidente în Cursor e prin Cmd+K (editare inline) și Panoul de chat.
Analiza instantanee a urmelor stivei
Când apare o excepție în consolă sau terminal, cel mai eficient flux de lucru este:
- Selectați întreaga urmărire a stivei în consolă
- Presa
Cmd+Shift+Lpentru a adăuga selecția în contextul de chat - Tu scrii: „Analizați această urmărire a stivei și identificați cauza principală. Arătați unde se află problema în cod și propuneți o remediere minimă.”
Cursorul nu citește doar prima linie a erorii. Urmează căile fișierelor din stivă, preluați codul relevant din proiectul dvs. și reconstruiți mental lanțul de apeluri care a provocat excepția.
// 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 pentru remedieri contextuale în linie
Când ați identificat deja linia problemei, Cmd+K si mai mult rapid pentru a aplica o remediere. Selectați codul problematic, apăsați Cmd+K și descrieți problema în limbajul natural. Cursorul modifică doar codul selectat, fără atingeți restul fișierului.
// 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'));
})
);
}
Puncte de control și rollback în timpul depanării
O caracteristică adesea trecută cu vederea la depanare și sistem Puncte de control de Cursor. Când explorați mai multe ipoteze de remediere, puteți salva starea curentă a bazei de cod ca punct de control și derulați înapoi dacă o încercare agravează situația.
Flux de lucru cu Checkpoint
- Înainte de a începe depanarea unei erori complexe, salvați un punct de control
- Încercați prima ipoteză de remediere cu Cursor
- Rulați testele: dacă eșuează, resetați punctul de control cu un singur clic
- Testați a doua ipoteză pornind de la o stare curată
- Continuați până când testele trec
Acest lucru elimină problema clasică „Am înrăutățit lucrurile și nu știu cum să mă întorc”. făcând explorarea soluțiilor mult mai puțin riscantă.
Configurați TypeScript/Angular Debugger în Cursor
Cursorul folosește același motor de depanare ca VS Code, ceea ce înseamnă că toate
launch.json că știi că lucrează identic. Diferența este că Cursorul
adaugă un strat AI în jurul procesului pentru a vă ajuta să interpretați ceea ce se întâmplă
și remediați problemele mai repede.
Configurați hărți sursă pentru TypeScript
Cerința cheie pentru depanarea eficientă TypeScript este configurarea corectă a hărților sursă. Fără ele, depanatorul indică în schimb fișiere JavaScript compilate decât la fișierele sursă TypeScript, ceea ce face imposibilă citirea codului în timpul depanării.
// 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"
}
]
}
Odată configurat launch.json, puteți porni depanatorul cu F5
ca în VS Code. Diferența cu Cursor este că puteți selecta un punct de întrerupere sau un întreg
funcția în panoul de depanare și cereți AI-ului să-și explice comportamentul sau să
sugerează de ce o variabilă are o valoare neașteptată.
Truc: Dezactivează TypeScriptul nativ al cursorului
În proiecte mari (monorepos, spații de lucru cu peste 100 de module), TypeScript Language Server de Cursor poate consuma multă memorie. Dacă observați încetinire sau blocări, adăugați acest lucru configurație pentru a utiliza TypeScript-ul proiectului în loc de cel intern al Cursorului:
// .cursor/settings.json
{
"typescript.enableNativePreview": false,
"typescript.tsdk": "./node_modules/typescript/lib"
}
Scurgeri de memorie, condiții de cursă și teste scazute cu AI
Aceste trei categorii de erori sunt din punct de vedere istoric cele mai dificil de depanat deoarece nu sunt deterministe. Ele apar intermitent, adesea doar în producție sau sub sarcină, iar încercările de a le izola adesea le elimină. AI-ul cursorului aduce un avantaj semnificativ chiar aici: poate analiza codul static pentru identifica modele care duc la aceste bug-uri, chiar înainte de a se manifesta.
Scurgeri de memorie în Angular: diagnostic și remediere
Cea mai comună scurgere de memorie în Angular este abonamentul RxJS negestionat. Dar ele există multe alte modele problematice pe care Cursor învață să le recunoască în proiectul tău specific.
// 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() { /* ... */ }
}
Condiții de cursă: model de diagnostic
Condițiile de cursă în Angular apar adesea atunci când solicitări HTTP multiple asincrone se completează într-o ordine imprevizibilă sau când starea componentei este actualizată după ce componenta a fost distrusă.
// 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) {}
}
Teste flaky: strategii de stabilizare
Testele flaky (testele care trec și eșuează intermitent) sunt una dintre probleme cel mai frustrant al dezvoltării moderne. Cursorul este deosebit de eficient la identificare cauzele deoarece poate analiza simultan testul, codul testat și tiparele de sincronizare.
// 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'
});
}));
Profilarea performanței asistată de AI
Depanarea performanței este o disciplină separată: nu este vorba despre găsirea erorilor, ci despre înțelege de ce ceva este lent. Cursorul nu înlocuiește profilerii dedicati precum Chrome DevTools sau Angular DevTools, dar accelerează foarte mult procesul de interpretare a datelor de profilare și implementarea optimizărilor.
Analizarea profilurilor de performanță cu cursorul
Cel mai eficient flux de lucru și capturați date de performanță cu instrumente native, apoi aduceți rezultatele în Cursor pentru analiza și implementarea corecțiilor.
// 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)
};
}
}
Integrare cu Chrome DevTools
Pentru depanarea avansată a performanței, cel mai puternic flux de lucru combină Chrome DevTools cu Cursor. Capturați un profil de performanță sau memorie în Chrome, exportați datele și cereți cursorului să le interpreteze în contextul bazei de cod.
// 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."
Flux de lucru de depanare: reproduce, izola, repara, testează
Nu este suficient să ai funcții puternice unice. Adevăratul avantaj competitiv vine din integrare aceste instrumente într-un flux de lucru repetabil și sistematic. Iată fluxul de lucru pe care dezvoltatorii mai productiv cu Cursor s-au standardizat.
Pasul 1: Joacă-te cu context maxim
Înainte de a atinge codul, adunați toate informațiile disponibile despre eroare. Cu cursorul, aceasta înseamnă oferirea AI cu cel mai bogat context posibil.
// 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: Izolați cu test minim
După ce ați identificat ipoteza cea mai probabilă, cereți-i lui Cursor să creeze un test care reproduce bug-ul izolat. Acest lucru are două avantaje: Testați ipoteza și oferă testare automată de regresie.
// 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: Remediere cu verificare incrementală
Cu testul de izolare la loc, aplicați remedierea și verificați imediat. Abordarea inversă TDD - mai întâi testul de regresie, apoi soluția - de ex deosebit de eficient cu Cursor, deoarece puteți repeta rapid.
// 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: Testul de regresie completă
După remediere, cereți cursorului să genereze o suită completă de teste care acoperă eroarea cazuri de margine fixe și aferente, pentru a se asigura că problema nu reapare.
// 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
Cele mai bune practici pentru depanarea asistată de AI
1. Întotdeauna contextul exact
Depanarea asistată de AI este la fel de bună ca contextul pe care îl furnizați. Diferența dintre un prompt vag și unul precis poate fi diferența dintre 10 minute si 2 ore de munca.
Principii pentru prompturi eficiente de depanare
- Urmărirea stivei complete: întotdeauna 5-10 rânduri, nu doar prima
- Comportamentul așteptat vs. observat: explică ambele
- Contextul fișierului: STATELE UNITE ALE AMERICII
@filename.tssă includă fișierele relevante - Ultima modificare: citați comiterea sau caracteristica dacă eroarea este recentă
- Mediu: dev/staging/prod schimbă adesea comportamentul
- Frecvenţă: mereu/intermitent/numai sub sarcină
2. Nu aveți încredere orbește în Fix AI
AI poate genera remedieri care abordează simptomul, dar nu cauza. Fluxul de lucru corect e întotdeauna: înțelegeți remedierea propusă, verificați-o prin teste și aprobă în mod conștient.
Anti-Pattern: Acceptarea corecțiilor fără a le înțelege
Modelul „depanare vibe” - cereți AI să repare o eroare, acceptați primul propunere fără a o înțelege, împingerea în producție - este cea mai rapidă modalitate de a acumula datorie tehnică. Fiecare remediere trebuie să fie:
- Se întâmplă la nivel logic
- Verificat cu cel puțin un test
- Revizuit pentru efecte secundare nedorite
3. Utilizați regulile cursorului pentru depanare
Puteți configura reguli de cursor specifice depanării care antrenează AI pe modelele proiectului dvs., evitând corecțiile care vă încalcă convențiile.
// .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. Sesiunile de depanare ca documentație
O bună practică avansată și tratați sesiunile de depanare ca oportunități de a documentatie. După remedierea unei erori complexe, cereți cursorului să genereze un comentariu explicativ în cod care documentează problema găsită și de ce solutia adoptata este cea corecta.
// 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 {
Instrumente de depanare și integrări
Integrare cu Datadog
Pentru echipele care folosesc Datadog în producție, extensia oficială Cursor vă permite aduceți datele de monitorizare a producției direct în IDE. Puteți adăuga puncte de conectare, vizându-le în Cursor și cereți agentului să vă ajute depanați erorile din producție pe baza jurnalelor și urmelor reale.
Configurați Datadog + Cursor
- Instalați extensia Datadog din extensiile cursor (compatibil VS Code)
- Configurați acreditările Datadog în setări
- În sesiunile de depanare, utilizați
@datadogpentru a aduce jurnalele reale în context - Cereți cursorului să coreleze erorile de producție cu codul sursă
Angular DevTools și Cursor
Angular DevTools în browser și un excelent profiler pentru probleme specifice Angular (detecție modificări, arbore de componente, injecție de dependență). Când găsești o problemă în profiler, aduceți informațiile în Cursor pentru analiza codului.
// 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
Depanare tradițională vs asistată de AI: când să folosiți ce
AI nu înlocuiește toate abordările de depanare. Există scenarii în care depanare manual tradițional și chiar superior sau complementar.
Ghid: ce abordare să utilizați
| Scenariu | Abordare recomandată | Instrumente |
|---|---|---|
| TypeScript / eroare de compilare | Cmd+K în linie | Editare inline cu cursorul |
| Urmărirea stivei cu eroare de rulare | Chat cu contextul fișierului | Cursor Chat + @file |
| Bug intermitent / stare de cursă | Modul de depanare | Modul de depanare cursor (2.2) |
| Scurgere progresivă de memorie | Profiler + analiză AI | Chrome DevTools + Cursor Chat |
| Regresia performanței | Profiler + optimizare AI | Angular DevTools + Cursor |
| Eroare în cod moștenit necunoscut | Modul de depanare + @codebase | Modul de depanare cursor + context |
| Hardware/depanare la nivel scăzut | Depanator nativ | gdb/lldb, puncte de întrerupere manuale |
| Vulnerabilități de securitate | Revizuirea manuală a codului | Cursor + recenzie umană expertă |
Concluzii: Construirea unei culturi a depanării asistate de AI
Depanarea cu Cursor AI nu este doar o chestiune de instrumente, este o schimbare de mentalitate. Cei mai productivi dezvoltatori nu „cere AI să repare erorile” - ei construiesc un dialog structurat cu AI, oferind context precis, verificând ipoteze cu teste, și folosirea instrumentelor potrivite pentru fiecare tip de problemă.
Modul de depanare al cursorului 2.2 reprezintă un salt calitativ: nu mai trebuie să fie experți în codul de bază pentru o depanare eficientă. Abordarea bazată pe ipoteză cu Instrumentul de rulare reduce dramatic timpul petrecut cu presupuneri. Bugbot se mișcă parte a sarcinii de detectare a erorilor la momentul revizuirii codului, reducând numărul de bug-uri care ajung în producție.
Pentru echipele Angular, câștigul este semnificativ mai ales în zone semnificative din punct de vedere istoric mai dificil: scurgeri de abonament, condiții de cursă în Observables, teste asincrone scazute și performanța detectării schimbărilor. Cursorul cunoaște aceste modele și le recunoaște rapid, unde un dezvoltator mai puțin experimentat ar putea dura ore întregi.
Lista de verificare pentru Noțiuni de bază cu depanarea asistată de AI
- Configurați
launch.jsoncu hărțile sursă activate - Abilitatea
sourceMap: trueÎntsconfig.json - Creați reguli de cursor pentru standardele de depanare ale proiectului dvs
- Exersați șablonul „RAPORT DE EROARE” în solicitările de depanare
- Experimentați cu modul Debug pe o eroare reală în baza de cod
- Configurați Bugbot dacă utilizați solicitări pull (GitHub/GitLab)
- Integrați fluxul de lucru: reproduceți - testați - reparați - verificați cu Cursor
Seria Cursor IDE continuă
Ați finalizat articolul de depanare. Continuați cu celelalte articole din serie:
- Articolul următor: Cursor vs Windsurf vs Copilot în 2026 - comparație completă a ISD AI pe piața actuală
- Pentru fluxuri de lucru complete: Flux de lucru profesional: Proiect unghiular cu cursor
- Pentru a automatiza verificările: Cârlige de cursor: automatizează fluxul de lucru
Serii încrucișate înrudite: MCP și Cursor pentru depanare cu date reale din baza de date, și seria Angular modern pentru cele mai bune practici specifice Angular.







