Exercício – depurar com o Visual Studio Code
É hora de colocar em prática seus novos conhecimentos de depuração. Acontece que temos a oportunidade perfeita. Em nosso aplicativo da Tailwind Traders, estamos desenvolvendo um novo recurso para permitir a exibição do preço de um produto em várias moedas. Um colega de trabalho escreveu um pouco de código, mas está com dificuldades para descobrir o que está dando errado. Vamos ajudar.
Criar um arquivo JavaScript em um workspace do Visual Studio
Para este exercício, você precisa de um arquivo JavaScript para praticar a depuração. Para usar os controles de inicialização do depurador, o arquivo JavaScript precisa estar em um workspace do Visual Studio.
O objetivo do aplicativo é definir a taxa de câmbio entre três moedas: USD, EUR e JPY. Em seguida, queremos exibir qual é o valor de 10 EUR
nas outras moedas usando dois dígitos após a casa decimal. Para cada moeda adicionada, a taxa de câmbio para todas as outras moedas deve ser calculada.
No Visual Studio Code, crie um arquivo chamado
mycurrency.js
na subpasta./nodejs-debug/
.Cole o seguinte código no editor do novo arquivo:
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');
Para salvar o arquivo, pressione Ctrl+S (Windows, Linux) ou Cmd+S (Mac).
Criar uma configuração de inicialização
Vamos usar muito o depurador, portanto, vamos criar uma configuração de inicialização para o aplicativo.
Na guia Executar no Visual Studio Code, selecione Criar um arquivo launch.json e selecione o depurador do Node.js.
O Visual Studio Code cria o arquivo de configuração
.vscode/launch.json
na raiz do workspace e abre o arquivo de inicialização para edição.Por padrão, é criada uma configuração de inicialização para executar o arquivo aberto no momento. Nesse exemplo, o arquivo aberto é
mycurrency.js
. Você pode modificar a configuração de inicialização para personalizar como o programa deve ser iniciado durante a depuração.Na configuração de inicialização, exiba o valor da propriedade
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 a raiz do workspace.
Feche o arquivo
.vscode/launch.json
.
Observação
Você pode criar diferentes configurações de inicialização para o projeto selecionando Adicionar Configuração no canto inferior direito.
Analisar os problemas
Verifique se o ambiente do Visual Studio Code está pronto para monitorar o processo de depuração:
- O painel do depurador deve ser aberto à esquerda. Use o ícone na guia Executar à esquerda para alternar a visibilidade do painel.
- O console de depuração deve ser aberto na parte inferior. Abra o console selecionando Exibir>Console de Depuração ou pressionando Ctrl+Shift+Y (Windows, Linux) ou Cmd+Shift+Y (Mac).
Agora, você já pode começar a depuração.
Nos controles de inicialização do depurador, inicie o programa com a depuração habilitada (a seta verde).
Você verá o programa ser concluído rapidamente. Isso é normal porque você ainda não adicionou nenhum ponto de interrupção.
Você deverá ver este texto no console de depuração, seguido por uma exceção.
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
O objetivo deste programa é definir a taxa de câmbio entre três moedas (USD, EUR, JPY) e exibir qual o valor de 10 EUR
em todas as outras moedas, com dois dígitos após uma casa decimal.
Podemos ver dois bugs aqui:
- Há mais de dois dígitos após a casa decimal.
- O programa falhou com uma exceção e não exibiu o valor de
JPY
.
Dica
- Defina
"outputCapture": "std",
em seu arquivo de configuração de inicialização para aumentar a saída do registro em log. - Defina um logpoint em vez de um ponto de interrupção para evitar interromper a execução do programa. Um logpoint não "interrompe" o depurador, mas, em vez disso, registra uma mensagem no console. Os logpoints são especialmente úteis para injetar log durante a depuração de servidores de produção que não podem ser pausados ou interrompidos.
Corrigir a exibição de dígitos
Começaremos com a correção do primeiro bug. Como você não escreveu esse código e funções diferentes estão sendo chamadas, vamos entender primeiro o fluxo de execução usando a execução passo a passo.
Usar pontos de interrupção e a execução passo a passo
Para adicionar um ponto de interrupção, selecione a linha 39 na margem esquerda, em printForeignValues(10, 'EUR');
.
Inicie a depuração novamente e intervenha na função printForeignValues()
com o controle de depuração Intervir:
Verificar estado das variáveis
Agora, dedique algum tempo a inspecionar os diferentes valores das variáveis no painel Variáveis.
- Quais são os valores das variáveis
value
esourceCurrency
? - Para a variável
rates
, você vê as três chaves esperadasUSD
,EUR
eJPY
?
Para avançar passo a passo até que a variável convertedValue
seja definida, use o controle de depuração Contornar:
Após usar o controle Contornar cinco vezes, você deverá ver o valor da variável convertedValue
definido como o 11.363636363636365
esperado.
Se contornarmos mais uma vez, veremos o valor da variável displayValue
. O valor deve ser a cadeia de caracteres formatada para exibição com dois dígitos 11.36
.
Podemos, então, concluir que até este ponto no programa, as funções convertToCurrency()
e formatValueForDisplay()
parecem corretas e retornam o resultado esperado.
Corrigir o erro
Use o controle Intervir uma vez para chegar à chamada à função console.info()
. Examine essa linha de código atentamente. Você vê o erro aqui?
Precisamos corrigir o bug do programa usando a variável displayValue
em vez da variável convertedValue
para imprimir o valor.
Atualize o arquivo
currency.js
para usar o nome correto da variável. Altere a chamada à funçãoconsole.info()
na linha 32 para usar a variáveldisplayValue
em vez da variávelconvertedValue
:console.info(`- ${displayValue} ${targetCurrency}`);
Salve as alterações no arquivo.
Reinicie o programa.
Verifique se o programa exibe corretamente o valor USD
como 11.36
. Primeiro bug: corrigido.
Encontrar a causa da falha
Agora, vamos descobrir por que o programa está falhando.
No arquivo
currency.js
, remova o ponto de interrupção definido na linha 39.Para forçar o programa a pausar após a exceção ser gerada, no painel Pontos de interrupção, marque a caixa Exceção Não Capturada.
Execute o programa no depurador novamente.
O programa deve pausar na exceção e mostrar um relatório de erros grande no meio da janela do editor.
Examine a linha em que a execução foi interrompida e observe a mensagem de exceção TypeError: Cannot read property 'toFixed' of undefined
. Com essa mensagem, você pode deduzir que a função de parâmetro value
tem o valor undefined
em vez de um número. Esse erro causou a exceção.
Retroceder a pilha de chamadas
O rastreamento de pilha que você vê abaixo da mensagem de erro pode ser um pouco difícil de decifrar. A boa notícia é que Visual Studio Code processa a pilha de chamadas de função para você. Por padrão, ele mostra apenas as informações significativas no painel Pilha de chamadas. Vamos usar informações da pilha de chamadas para localizar o código que levou a essa exceção.
Sabemos que a exceção foi lançada na chamada à função formatValueForDisplay()
.
No painel do depurador, vá até o painel Pilha de chamadas.
Para ver onde a função
formatValueForDisplay()
foi chamada, clique duas vezes na função abaixo dela; a funçãoprintForeignValues
.O Visual Studio Code vai até a linha na função
printForeignValues
em seu arquivocurrency.js
, em que a funçãoformatValueForDisplay()
foi chamada:const displayValue = formatValueForDisplay(convertedValue);
Examine atentamente esta linha de código. O parâmetro que está causando a exceção é proveniente da variável convertedValue
. Você precisa descobrir em que ponto o valor desse parâmetro se torna undefined
.
Uma opção é adicionar um ponto de interrupção nessa linha e, então, inspecionar a variável sempre que o ponto de interrupção parar na linha. No entanto, não sabemos quando o valor errado pode ocorrer e, em programas complexos, essa abordagem de depuração pode ser complicada. Vamos examinar um método alternativo.
Adicionar um ponto de interrupção condicional
Em nosso caso, seria útil fazer com que o depurador parasse neste ponto de interrupção somente quando o valor da variável convertedValue
fosse undefined
. Felizmente, o Visual Studio Code pode fazer isso usando as opções corretas de clique com o mouse.
No arquivo
currency.js
, na margem esquerda na linha 31, clique com o botão direito do mouse e selecione Adicionar Ponto de Interrupção Condicional.Após clicar com o botão direito do mouse, insira a seguinte condição para disparar o ponto de interrupção e pressione Enter:
`convertedValue === undefined`
Reinicie o programa.
Agora, o programa deve parar na linha 31 e podemos examinar os valores da pilha de chamadas.
Observar o estado atual
Vamos dedicar algum tempo a analisar o estado do programa atual.
O valor da variável
convertedValue
vem da chamada à funçãoconvertToCurrency(value, sourceCurrency, targetCurrency)
. Precisamos verificar os valores de parâmetro nesta chamada de função e confirmar se estão corretos.Especificamente, precisamos examinar a variável
value
e confirmar que ela tem o valor esperado10
.
Dê uma olhada no código da função convertToCurrency()
.
function convertToCurrency(value, sourceCurrency, targetCurrency) {
const exchangeRate = rates[sourceCurrency][targetCurrency];
return exchangeRate && value * exchangeRate;
}
Você sabe que o resultado desse código é undefined
. Você também sabe que a variável value
está definida como 10
. Essas informações nos ajudam a ver que o problema deve estar no valor da variável exchangeRate
.
No arquivo currency.js
, passe o mouse sobre a variável rates
para dar uma olhada:
Você tenta obter a taxa de câmbio de EUR
para JPY
, mas se desdobrar o valor EUR
, verá que há apenas uma taxa de conversão para USD
. A taxa de conversão para JPY
está ausente.
Corrigir taxas de conversão ausentes
Agora que você sabe que algumas taxas de conversão estão ausentes, vamos entender o porquê. Para remover todos os pontos de interrupção existentes, no painel Pontos de Interrupção, selecione o ícone Remover todos os pontos de interrupção.
Inspecionar a variável rates
Vamos definir um ponto de interrupção para inspecionar a variável rates
.
No arquivo
currency.js
, adicione um ponto de interrupção na linha37
na funçãosetExchangeRate(0.88, 'USD', 'EUR');
.No painel Inspeção, selecione Mais e insira
rates
.Sempre que o valor da variável
rates
é alterado, o valor atualizado é mostrado no painel Inspeção.Reinicie o programa.
Quando o ponto de interrupção parar na primeira chamada à função
setExchangeRate()
, use o controle Contornar.No painel Inspeção, examine o valor da variável
rates
.Neste ponto,
USD
eEUR
têm taxas de conversão opostas correspondentes, como esperado.Contorne novamente na segunda chamada para a função
setExchangeRate()
.Você vê que
USD
eJPY
têm taxas de conversão opostas correspondentes, mas não há nada entreEUR
eJPY
.
É hora de examinar o código para a função 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;
}
As linhas mais importantes nesta função são as duas últimas. Parece que você encontrou o segundo bug! As taxas de conversão são definidas apenas entre as variáveis sourceCurrency
e targetCurrency
. O programa também precisa calcular a taxa de conversão para as outras moedas adicionadas.
Corrigir o código
Vamos corrigir o código para o problema da taxa de conversão.
Atualize seu arquivo
currency.js
para calcular a taxa de conversão das outras moedas.Substitua o código nas linhas 12 e 13:
rates[sourceCurrency][targetCurrency] = rate; rates[targetCurrency][sourceCurrency] = 1 / rate;
por este código atualizado:
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); } }
Salve as alterações no arquivo.
O código atualizado define a taxa de conversão de qualquer outra moeda diferente de sourceCurrency
e targetCurrency
. O programa usa a taxa de conversão de sourceCurrency
para deduzir a taxa entre a outra moeda e targetCurrency
. Em seguida, o código define a taxa de conversão para a outra moeda adequadamente.
Observação
Essa correção só funcionará se as taxas entre sourceCurrency
e as outras moedas já existirem, o que é uma limitação aceitável nesse caso.
Testar a correção
Vamos testar nossa alteração.
Remova todos os pontos de interrupção e inspecione as variáveis.
Reinicie o programa.
Agora você deverá ver o resultado esperado no console, sem nenhuma falha.
The value of 10 EUR is:
- 11.36 USD
- 1220.45 JPY
É isso. Você corrigiu o código. Agora você pode depurar com eficiência códigos desconhecidos com antecedência usando o Visual Studio Code. Muito bem!
Limpar o contêiner de desenvolvimento
Depois de concluir o projeto, limpe o ambiente de desenvolvimento ou devolva-o ao estado padrão.
A exclusão do ambiente GitHub Codespaces garante que você possa maximizar a quantidade de horas gratuitas por núcleo que você tem direito na sua conta.
Importante
Para saber mais sobre os direitos da sua conta do GitHub, confira O GitHub Codespaces inclui mensalmente armazenamento e horas de núcleo.
Entre no painel do GitHub Codespaces (https://github.com/codespaces).
Localize seus Codespaces atualmente em execução, originados do repositório
MicrosoftDocs/node-essentials
do GitHub.Abra o menu de contexto do codespace e selecione Excluir.