Esercizio - Eseguire il debug con Visual Studio Code
È il momento di mettere in pratica le conoscenze appena acquisite sul processo di debug. L'applicazione costituisce un'ottima occasione. Nell'app di Tailwind Traders si sta sviluppando una nuova funzionalità che consente di visualizzare il prezzo di un prodotto in più valute. Un collega ha scritto il codice, ma ha alcune difficoltà nel capire cosa non funzioni esattamente. Si proverà a rendersi utili.
Creare un file JavaScript in un'area di lavoro Visual Studio
Per questo esercizio è necessario un file JavaScript per eseguire il debug. Per usare i controlli di avvio del debugger, il file JavaScript deve trovarsi in un'area di lavoro Visual Studio.
L'obiettivo dell'applicazione è impostare il tasso di cambio tra tre valute, USD, EUR e SHORT. Successivamente, si intende visualizzare il valore 10 EUR
in tutte le altre valute, con due cifre dopo il separatore decimale. Per ogni valuta aggiunta, è necessario calcolare il tasso di cambio per tutte le altre valute.
In Visual Studio Code creare un file denominato
mycurrency.js
nella sottocartella./nodejs-debug/
.Incollare il codice seguente nell'editor del nuovo file:
const rates = {}; function setExchangeRate(rate, sourceCurrency, targetCurrency) { if (rates[sourceCurrency] === undefined) { rates[sourceCurrency] = {}; } if (rates[targetCurrency] === undefined) { rates[targetCurrency] = {}; } rates[sourceCurrency][targetCurrency] = rate; rates[targetCurrency][sourceCurrency] = 1 / rate; } function convertToCurrency(value, sourceCurrency, targetCurrency) { const exchangeRate = rates[sourceCurrency][targetCurrency]; return exchangeRate && value * exchangeRate; } function formatValueForDisplay(value) { return value.toFixed(2); } function printForeignValues(value, sourceCurrency) { console.info(`The value of ${value} ${sourceCurrency} is:`); for (const targetCurrency in rates) { if (targetCurrency !== sourceCurrency) { const convertedValue = convertToCurrency(value, sourceCurrency, targetCurrency); const displayValue = formatValueForDisplay(convertedValue); console.info(`- ${convertedValue} ${targetCurrency}`); } } } setExchangeRate(0.88, 'USD', 'EUR'); setExchangeRate(107.4, 'USD', 'JPY'); printForeignValues(10, 'EUR');
Per salvare il file, premere CTRL+S (Windows, Linux) o CMD+S (Mac).
Creare una configurazione di avvio
In questo esempio si userà molto il debugger, quindi si procederà alla creazione di una configurazione di avvio per l'app.
Nella scheda Esegui in Visual Studio Code selezionare Crea un file launch.json e selezionare il debugger Node.js.
In Visual Studio Code viene creato il file di configurazione
.vscode/launch.json
nella radice dell'area di lavoro e viene aperto il file di avvio per la modifica.Per impostazione predefinita, viene creata una configurazione di avvio per eseguire il file attualmente aperto. Il questo esempio, il file di avvio è
mycurrency.js
. È possibile modificare la configurazione di avvio per personalizzare il modo in cui il programma si avvia quando si esegue il debug.Nella configurazione di avvio visualizzare il valore della proprietà
program
.{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Program", "skipFiles": [ "<node_internals>/**" ], "program": "${workspaceFolder}/nodejs-debug/mycurrency.js" } ] }
${workspaceFolder}
indica la radice dell'area di lavoro.
Chiudere il file
.vscode/launch.json
.
Nota
È possibile creare configurazioni di avvio diverse per il progetto selezionando Aggiungi configurazione in basso a destra.
Analizzare i problemi
Verificare che l'ambiente di Visual Studio Code sia pronto per monitorare il processo di debug:
- Il pannello del debugger deve essere aperto a sinistra. Usare l'icona della scheda Esegui a sinistra per attivare o disattivare la visibilità del pannello.
- La console di debug deve essere aperta nella parte inferiore. Per aprire la console, selezionare Visualizza>Console di debug o premere CTRL+MAIUSC+Y (Windows, Linux) o CMD+MAIUSC+Y (Mac).
A questo punto è possibile avviare il processo di debug.
Nei controlli di avvio del debugger avviare il programma con il debug abilitato (freccia verde).
Si noterà che il programma termina rapidamente. Ciò è normale perché non sono ancora stati aggiunti punti di interruzione.
Si dovrebbe vedere questo testo nella console di debug, seguito da un'eccezione.
The value of 10 EUR is:
11.363636363636365
- 11.363636363636365 USD
/app/node-101/currency.js:23
return value.toFixed(2);
^
TypeError: Cannot read property 'toFixed' of undefined
at formatValueForDisplay (/app/node-101/currency.js:23:16)
at printForeignValues (/app/node-101/currency.js:32:28)
at Object.<anonymous> (/app/node-101/currency.js:40:1)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
at internal/main/run_main_module.js:17:11
Lo scopo di questo programma è impostare il tasso di cambio fra tre valute (USD, EUR, JPY) e visualizzare il valore di 10 EUR
in tutte le altre valute, con due cifre dopo il separatore decimale.
Si possono notare due bug:
- Ci sono più di due cifre dopo il separatore decimale.
- Si è verificato un arresto anomalo del programma con un'eccezione e non è stato possibile visualizzare il valore per
JPY
.
Suggerimento
- Impostare
"outputCapture": "std",
nel file di configurazione di avvio per aumentare l'output della registrazione. - Impostare un punto di inserimento istruzione di registrazione anziché un punto di interruzione per evitare di arrestare l'esecuzione del programma. Un punto di inserimento istruzione di registrazione non si interrompe nel debugger, ma registra invece un messaggio alla console. I punti di inserimento istruzione di registrazione sono particolarmente utili per inserire la registrazione durante il debug dei server di produzione che non possono essere sospesi o arrestati.
Correggere la visualizzazione delle cifre
Iniziare correggendo il primo bug. Dal momento che il codice non è stato scritto personalmente e ci sono diverse funzioni che vengono chiamate, per prima cosa occorre comprendere il flusso di esecuzione procedendo un'istruzione alla volta.
Usare i punti di interruzione e l'esecuzione un'istruzione alla volta
Per aggiungere un punto di interruzione, selezionare nel margine sinistro alla riga 39, in printForeignValues(10, 'EUR');
.
Avviare nuovamente il debug e passare alla funzione printForeignValues()
con il controllo di debug Esegui istruzione:
Controllare lo stato delle variabili
Esaminare i valori delle diverse variabili nel riquadro Variabili.
- Quali sono i valori per le variabili
value
esourceCurrency
? - Per le variabili
rates
, sono presenti le tre chiavi previste,USD
,EUR
eJPY
?
Per procedere eseguendo un passaggio alla volta fino all'impostazione della variabile convertedValue
, usare il controllo di debug Esegui istruzione/routine:
Dopo aver usato il controllo Esegui istruzione/routine cinque volte, viene visualizzato il valore della variabile convertedValue
impostato come previsto 11.363636363636365
.
Se si esegue l'istruzione ancora una volta, viene visualizzato il valore della variabile displayValue
. Il valore deve essere la stringa formattata per la visualizzazione con due cifre 11.36
.
Si può quindi concludere che, fino a questo punto, le funzioni convertToCurrency()
e formatValueForDisplay()
sembrano corrette e restituiscono il risultato previsto.
Correggere l'errore
Usare il controllo Esegui istruzione una sola volta per raggiungere la chiamata alla funzione console.info()
. Esaminare attentamente questa riga di codice. Si vede l'errore?
È necessario correggere il bug del programma usando la variabile displayValue
anziché la variabile convertedValue
per stampare il valore.
Aggiornare il file
currency.js
per usare il nome di variabile corretto. Modificare la chiamata alla funzioneconsole.info()
sulla riga 32 per usare la variabiledisplayValue
anziché la variabileconvertedValue
:console.info(`- ${displayValue} ${targetCurrency}`);
Salvare le modifiche apportate al file.
Riavviare il programma.
Verificare che il programma visualizzi correttamente il valore USD
come 11.36
. Primo bug - risolto.
Trovare la causa dell'arresto anomalo
Ora si scoprirà perché si verifica un arresto anomalo del programma.
Nel file
currency.js
rimuovere il punto di interruzione impostato alla riga 39.Per forzare la sospensione del programma dopo la generazione dell'eccezione, nel riquadro Punti di interruzione selezionare la casella Eccezioni non rilevate.
Eseguire di nuovo il programma nel debugger.
Il programma viene sospeso in corrispondenza dell'eccezione con un report di errore di grandi dimensioni all'interno della finestra dell'editor.
Esaminare la riga in cui l'esecuzione è stata interrotta e notare il messaggio di eccezione TypeError: Cannot read property 'toFixed' of undefined
. Da tale messaggio è possibile dedurre che il valore della funzione di parametro value
è undefined
e non un numero. Questo errore è quello che ha causato l'eccezione.
Riavvolgere lo stack di chiamate
L'analisi dello stack visualizzata sotto il messaggio di errore può essere difficile da decifrare. Visual Studio Code è però in grado di elaborare automaticamente lo stack di chiamate di funzione. Per impostazione predefinita, nel riquadro Stack di chiamate vengono visualizzate solo le informazioni significative. Vengono usate ora le informazioni sullo stack di chiamate per trovare il codice che ha causato l'eccezione.
È noto che l'eccezione è stata generata nella chiamata alla funzione formatValueForDisplay()
.
Nel pannello del debugger andare al riquadro Stack di chiamate.
Per vedere dove è stata chiamata la funzione
formatValueForDisplay()
, fare doppio clic sulla funzione sottostante, ovveroprintForeignValues
.Visual Studio Code passa alla riga nella funzione
printForeignValues
nel filecurrency.js
, dove la funzioneformatValueForDisplay()
è stata chiamata:const displayValue = formatValueForDisplay(convertedValue);
Esaminare attentamente questa riga di codice. Il parametro che causa l'eccezione deriva dalla variabile convertedValue
. È ora necessario scoprire in quale punto il valore diventa undefined
.
Un'opzione consiste nell'aggiungere un punto di interruzione in questa riga esaminando la variabile ogni volta che il punto di interruzione la raggiunge. Non sappiamo tuttavia quando potrebbe essere generato il valore errato e in programmi complessi questo approccio di debug può essere complesso. Esaminiamo un metodo alternativo.
Aggiungere un punto di interruzione condizionale
Ciò che sarebbe utile nel nostro caso è la possibilità di arrestare il debugger in questo punto di interruzione solo quando il valore della variabile convertedValue
è undefined
. Fortunatamente, in Visual Studio Code questa azione può essere eseguita con diverse opzioni associate al pulsante destro del mouse.
Nel file
currency.js
, nel margine sinistro della riga 31 fare clic con il pulsante destro del mouse e selezionare Aggiungi punto di interruzione condizionale.Dopo aver fatto clic con il pulsante destro del mouse, immettere la condizione seguente per attivare il punto di interruzione, quindi premere INVIO:
`convertedValue === undefined`
Riavviare il programma.
Il programma deve ora arrestarsi sulla riga 31 ed è possibile esaminare i valori dello stack di chiamate.
Osservare lo stato corrente
Analizziamo ora lo stato corrente del programma.
Il valore della variabile
convertedValue
deriva dalla chiamata alla funzioneconvertToCurrency(value, sourceCurrency, targetCurrency)
. È necessario controllare i valori dei parametri nella chiamata alla funzione per verificare che siano corretti.In particolare, è necessario esaminare la variabile
value
e verificare che abbia il valore10
previsto.
Esaminare il codice della funzione convertToCurrency()
.
function convertToCurrency(value, sourceCurrency, targetCurrency) {
const exchangeRate = rates[sourceCurrency][targetCurrency];
return exchangeRate && value * exchangeRate;
}
Si sa che il risultato di questo codice è undefined
Si sa anche che il valore della variabile value
è impostato su 10
. Queste informazioni consentono di capire che il problema è correlato al valore della variabile exchangeRate
.
Nel file currency.js
passare il puntatore sulla variabile rates
per esaminarla:
Si cerca di ottenere il tasso di cambio da EUR
a JPY
, ma se si espande il valore EUR
è possibile vedere che è presente solo un tasso di conversione per USD
. Il tasso di conversione per JPY
non è presente.
Correggere i tassi di conversione mancanti
Ora che si sa che alcuni tassi di conversione risultano mancanti, è necessario comprenderne il motivo. Per rimuovere tutti i punti di interruzione esistenti, selezionare Rimuovi tutti i punti di interruzione nel riquadro Punti di interruzione.
Controllare la variabile rates
Impostare un punto di interruzione per controllare la variabile rates
.
Nel file
currency.js
aggiungere un punto di interruzione sulla riga37
nella funzionesetExchangeRate(0.88, 'USD', 'EUR');
.Nel riquadro Espressione di controllo selezionare Più, quindi immettere
rates
.Ogni volta che il valore della variabile
rates
viene modificato, il valore aggiornato viene visualizzato nel riquadro Espressione di controllo.Riavviare il programma.
Quando il punto di interruzione si arresta alla prima chiamata alla funzione
setExchangeRate()
, usare il controllo Esegui istruzione/routine.Nel riquadro Espressione di controllo esaminare il valore della variabile
rates
.A questo punto è possibile notare che
USD
eEUR
hanno tassi di conversione opposti corrispondenti, come previsto.Eseguire di nuovo il passaggio alla seconda chiamata alla funzione
setExchangeRate()
.Si noterà che
USD
eJPY
hanno tassi di conversione opposti corrispondenti, ma che non c'è niente traEUR
eJPY
.
È il momento di esaminare il codice per la funzione setExchangeRate()
.
function setExchangeRate(rate, sourceCurrency, targetCurrency) {
if (rates[sourceCurrency] === undefined) {
rates[sourceCurrency] = {};
}
if (rates[targetCurrency] === undefined) {
rates[targetCurrency] = {};
}
rates[sourceCurrency][targetCurrency] = rate;
rates[targetCurrency][sourceCurrency] = 1 / rate;
}
Le righe più importanti della funzione sono le ultime due. Sembra che il secondo bug sia stato identificato. I tassi di conversione vengono impostati solo tra le variabili sourceCurrency
e targetCurrency
. Il programma deve anche calcolare il tasso di conversione per le altre valute aggiunte.
Correggere il codice
È possibile correggere il codice per il problema di frequenza di conversione.
Aggiornare il file
currency.js
per calcolare il tasso di conversione per le altre valute.Sostituire il codice nelle righe 12 e 13:
rates[sourceCurrency][targetCurrency] = rate; rates[targetCurrency][sourceCurrency] = 1 / rate;
con questo codice aggiornato:
for (const currency in rates) { if (currency !== targetCurrency) { // Use a pivot rate for currencies that don't have the direct conversion rate const pivotRate = currency === sourceCurrency ? 1 : rates[currency][sourceCurrency]; rates[currency][targetCurrency] = rate * pivotRate; rates[targetCurrency][currency] = 1 / (rate * pivotRate); } }
Salvare le modifiche apportate al file.
Il codice aggiornato imposta il tasso di conversione per qualsiasi valuta diversa da sourceCurrency
e targetCurrency
. Il programma usa il tasso di conversione di sourceCurrency
per dedurre il tasso tra l'altra valuta e targetCurrency
. Il codice imposta di conseguenza il tasso di conversione per l'altra valuta.
Nota
Questa correzione funziona solo se i tassi tra sourceCurrency
e le altre valute esistono già, limitazione che in questo caso è accettabile.
Testare la correzione
È il momento di testare la modifica apportata.
Rimuovere tutti i punti di interruzione e controllare le variabili.
Riavviare il programma.
Nella console verrà ora visualizzato il risultato previsto, senza arresti anomali.
The value of 10 EUR is:
- 11.36 USD
- 1220.45 JPY
È tutto. Il codice è stato corretto. A questo punto, si è in grado di eseguire in modo efficiente il debug di codice mai visto prima usando Visual Studio Code. le due dipendenze nell'app.
Pulire il contenitore di sviluppo
Dopo aver completato il progetto, è possibile scegliere di pulire l'ambiente di sviluppo o riportarlo allo stato tipico.
L'eliminazione dell'ambiente GitHub Codespaces offre la possibilità di aumentare le ore gratuite per core a cui si ha diritto per l'account.
Importante
Per altre informazioni sui diritti dell'account GitHub, vedere Ore di archiviazione e di core mensili incluse in GitHub Codespaces.
Accedere al dashboard di GitHub Codespaces (https://github.com/codespaces).
Individuare il codespaces attualmente in esecuzione originato dal
MicrosoftDocs/node-essentials
repository GitHub.Aprire il menu di scelta rapida per il codespace e scegliere Elimina.