3
respostas

Executando o pegaArquivo duas vezes, estou recebendo apenas a promessa rejected

Interessante, ao executar o código de forma seguida, recebo diferentes outputs da execução. As vezes recebo a resposta esperada recebida no vídeo, as vezes recebo apenas a mensagem de erro, sem a leitura do arquivo. Alguém saberia dizer a que se deve esta diferença de resposta?

Código usado:

import fs from 'fs';
import chalk from 'chalk';

function trataErro(erro) {
    console.log(erro);
    throw new Error(chalk.red(erro.code, 'erro ao ler arquivo'))
}

// Async/await

async function pegaArquivo(caminhoDoArquivo) {
    try {
        const encoding = 'utf-8';
        const texto = await fs.promises.readFile(caminhoDoArquivo, encoding);
        console.log(chalk.green(texto));
    } catch (erro) {
        trataErro(erro);
    }
}

pegaArquivo('./arquivos/texto.md');
pegaArquivo('./arquivos/');

Recebendo apenas o erro:

PS C:\Cursos\Alura\2708-node-lib-md> node index.js
[Error: EISDIR: illegal operation on a directory, read] {
  errno: -4068,
  code: 'EISDIR',
  syscall: 'read'
}
file:///C:/Cursos/Alura/2708-node-lib-md/index.js:6
    throw new Error(chalk.red(erro.code, 'erro ao ler arquivo'))
          ^

Error: EISDIR erro ao ler arquivo
    at trataErro (file:///C:/Cursos/Alura/2708-node-lib-md/index.js:6:11)
    at pegaArquivo (file:///C:/Cursos/Alura/2708-node-lib-md/index.js:17:9)

Node.js v18.9.0

Inclusive se eu utilizar:

// Pegando um arquivo inexistente em vez de um diretório
pegaArquivo('./arquivos/teste');

Sempre recebo apenas a mensagem de erro, não recebo a promessa fulfilled.

3 respostas

Boa noite Eugenio, tudo bem?

Normalmente quando esse erro ocorre é devido ao arquivo dentro da pasta, faça as seguintes verificações:

  1. Verifique se o arquivo existe. Se não, você precisa criá-lo. (Se o NPM depender de alguma informação específica no arquivo, você precisará ter essa informação lá).
  2. Certifique-se de que é de fato um arquivo e não um diretório.
  3. Tem as permissões certas. Você pode alterar o arquivo para ter todas as permissões com "sudo chmod 777 FILE_NAME". (Cuidado: você está dando permissões de leitura, gravação e execução para cada um nesse arquivo)

Boa noite,

No caso estava testando justamente com um arquivo inexistente.

Na aula se testou fazer com um diretório existente para ver a mensagem de erro.

Ao testar com um arquivo inexistente que fiquei apenas com o erro. É normal este comportamento?

Atenciosamente,

Eugenio Pacheco

EDIT:

Fiz mais alguns testes e parece não ser relacionado exatamente à versão do Node.js e sim à sincronicidade/assincronicidade das funções e à forma como elas estão sendo executadas a nível de sistema operacional.

Como a função pegaArquivo() trabalha com promessas (ou seja, de forma assíncrona), ao executarmos a mesma função duas vezes, uma em seguida da outra, existe a possibilidade de que os retornos não ocorram na mesma ordem de chamada. Por exemplo, a função que recebe o parâmetro correto poderia "demorar" um pouco mais para retornar o texto do que o tempo que a função que recebe o parâmetro errado levaria retornar o erro (ou, como estamos usando throw, "lançar" o erro).

Um dos pontos aqui é justamente o throw. Como este recurso interrompe a execução do programa, se a função "incorreta" executar antes, o throw encerra o programa antes que a função "correta" retorne o texto, e por isso somente o erro é exibido no terminal. Caso queira, pode fazer o teste com a seguinte alteração na função pegaArquivo():

async function pegaArquivo(caminhoDoArquivo) {
  try {
    const encoding = 'utf-8';
    const texto = await fs.promises.readFile(caminhoDoArquivo, encoding)
    console.log(chalk.green(texto))
  } catch(erro) {
    // trataErro(erro);
    console.log('aqui deu erro!');
  }
}

Ao substituirmos o throw por um console.log() (que não interrompe a execução do programa) tudo funciona normalmente.

Outro teste que podemos fazer é colocar a segunda chamada da função dentro de uma função setInterval(), que vai "aguardar" 5 segundos antes de executar:

async function pegaArquivo(caminhoDoArquivo) {
  try {
    const encoding = 'utf-8';
    const texto = await fs.promises.readFile(caminhoDoArquivo, encoding)
    console.log(chalk.green(texto))
  } catch(erro) {
    trataErro(erro);
  }
}

pegaArquivo('./arquivos/texto1.md');
setInterval(() => pegaArquivo('./arquivos/'), 5000);

Com essa pausa, damos um tempinho para que a função "correta" retorne o texto no terminal antes da execução da função "incorreta".

Faça o teste ;) Bons estudos!


Olá!

Estamos tentando aqui reproduzir o seu erro, pois está aparecendo de forma intermitente entre minors da versão 18 do Node.js - por exemplo, o erro está ocorrendo no Linux na versão 18.7.0 e no Windows está ocorrendo na versão 18.9.1. Está me parecendo um bug de interpretação interna do próprio Node.js. Como a 18 ainda não entrou como LTS (isso vai acontecer em alguns dias) é bem provável que seja corrigido com rapidez.

Vamos continuar investigando e, se ainda for necessário, fazemos um adendo no conteúdo após o lançamento da v18 como LTS.

Obrigada por avisar e bons estudos ;)