Esercizio - Eseguire il debug con Visual Studio Code

Completato

È 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.

  1. In Visual Studio Code creare un file denominato mycurrency.js nella sottocartella ./nodejs-debug/.

  2. 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');
    
  3. 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.

  1. 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.

    Screenshot of generated launch configuration.

    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.

  2. 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.
  3. 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).

Screenshot of the Start debugging button in Visual Studio Code.

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');.

Screenshot of the breakpoint location in the code.

Avviare nuovamente il debug e passare alla funzione printForeignValues() con il controllo di debug Esegui istruzione:

Screenshot of the Step into button.

Controllare lo stato delle variabili

Esaminare i valori delle diverse variabili nel riquadro Variabili.

Screenshot of the Variables pane.

  • Quali sono i valori per le variabili value e sourceCurrency?
  • Per le variabili rates, sono presenti le tre chiavi previste, USD, EUR e JPY?

Per procedere eseguendo un passaggio alla volta fino all'impostazione della variabile convertedValue, usare il controllo di debug Esegui istruzione/routine:

Screenshot of the Step over button.

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.

  1. Aggiornare il file currency.js per usare il nome di variabile corretto. Modificare la chiamata alla funzione console.info() sulla riga 32 per usare la variabile displayValue anziché la variabile convertedValue:

    console.info(`- ${displayValue} ${targetCurrency}`);
    
  2. Salvare le modifiche apportate al file.

  3. 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.

  1. Nel file currency.js rimuovere il punto di interruzione impostato alla riga 39.

  2. Per forzare la sospensione del programma dopo la generazione dell'eccezione, nel riquadro Punti di interruzione selezionare la casella Eccezioni non rilevate.

  3. 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.

Screenshot of the exception message shown in Visual Studio Code.

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().

  1. Nel pannello del debugger andare al riquadro Stack di chiamate.

  2. Per vedere dove è stata chiamata la funzione formatValueForDisplay(), fare doppio clic sulla funzione sottostante, ovvero printForeignValues.

    Visual Studio Code passa alla riga nella funzione printForeignValues nel file currency.js, dove la funzione formatValueForDisplay() è 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.

  1. 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.

    Screenshot of setting a conditional breakpoint in Visual Studio Code.

  2. 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`
    
  3. 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 funzione convertToCurrency(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 valore 10 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:

Screenshot of peeking at the rates variable value.

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.

Screenshot of the button to remove all breakpoints.

Controllare la variabile rates

Impostare un punto di interruzione per controllare la variabile rates.

  1. Nel file currency.js aggiungere un punto di interruzione sulla riga 37 nella funzione setExchangeRate(0.88, 'USD', 'EUR');.

  2. 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.

  3. Riavviare il programma.

  4. Quando il punto di interruzione si arresta alla prima chiamata alla funzione setExchangeRate(), usare il controllo Esegui istruzione/routine.

  5. Nel riquadro Espressione di controllo esaminare il valore della variabile rates.

    A questo punto è possibile notare che USD e EUR hanno tassi di conversione opposti corrispondenti, come previsto.

  6. Eseguire di nuovo il passaggio alla seconda chiamata alla funzione setExchangeRate().

    Si noterà che USD e JPY hanno tassi di conversione opposti corrispondenti, ma che non c'è niente tra EUR e JPY.

È 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.

  1. 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);
      }
    }
    
  2. 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.

  1. Rimuovere tutti i punti di interruzione e controllare le variabili.

  2. 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.

  1. Accedere al dashboard di GitHub Codespaces (https://github.com/codespaces).

  2. Individuare il codespaces attualmente in esecuzione originato dal MicrosoftDocs/node-essentials repository GitHub.

    Screenshot of all the running Codespaces including their status and templates.

  3. Aprire il menu di scelta rapida per il codespace e scegliere Elimina.

    Screenshot of the context menu for a single codespace with the delete option highlighted.