Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

278
Visualizações
PDF Data Size 0 in Node/Express

I'm working on something that grabs a PDF from my Google Cloud Storage. The PDF URL is in the entry in MongoDB. Actually pulling the file down works fine. But I'm having an issue with actually getting it to send to the client. I think the problem lies with the data it's reading somehow ending up empty, so I assume it has to do with async or callbacks or promises or something of the like. However, I can't figure out where the error is happening. Any advice as to what I'm missing would be greatly appreciated. Here is the main code:

router.get('/:slug', async function(req, res) {
    const slug = req.params.slug;
    let fullPath;
    const find = await Entry.findOne({slug: slug}, (err, data) => {
        if(err) {
            res.render('error.ejs');
        }
        else {
            console.log(data.fileURL);
            getFile(data.fileURL).then(async (fileName) => {
                fullPath = dir.APP_DIR + fileName;
                console.log(fullPath);
                fs.readFile(fullPath, async (err, data) => {
                    if(err || data.length == 0) {
                        res.render('error.ejs', {session: req.session});
                    }
                    else {
                        console.log('Full path is: ' + fullPath);
                        console.log(data.length);
                        res.writeHead(200, {
                            'Content-Type': 'application/pdf',
                            'Content-disposition': 'inline',
                            'Content-Length': data.length

                        }).end(Buffer.from(data, 'binary'));
                    }
                })
            });
        }      
    });
});

The getFile function is exported, and it is as follows:

async function getFile(fileURL) {
    const url = fileURL;
    console.log(url);
    const newFileName = '/pdf_files/' + genID() + '.pdf';
    const file = fs.createWriteStream('.' + newFileName);
        https.get(url, function(response) {
            response.pipe(file);
            file.on('finish', function() {
                file.close();
            });
        });
        return newFileName;
    }
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

So in theory your code seems fine. I have some legibility optimizations so that the flow of data might appear a bit clearer. These changes are reflected below.

Obliviously I do not know if this will fix your issue, but to me it seems, like you have a race condition in your getFile() function. You return the new file name, but are not waiting for the file to actually be written. Then you immediately try and read it which will most likely not work. The writing is async and thus might not be done.

Here are my proposed changes:

Your main code:

router.get('/:slug', async function (req, res) {
    const slug = req.params.slug;
    let fullPath;
    try {
        const data = await Entry.findOne({slug});
                console.log(data.fileURL);
                fileName = await getFile(data.fileURL);
                    fullPath = dir.APP_DIR + fileName;
                    console.log(fullPath);
                    fs.readFile(fullPath, async (err, data) => {
                        if (err || data.length == 0) {
                            res.render('error.ejs', {
                                session: req.session
                            });
                        } else {
                            console.log('Full path is: ' + fullPath);
                            console.log(data.length);
                            res.writeHead(200, {
                                'Content-Type': 'application/pdf',
                                'Content-disposition': 'inline',
                                'Content-Length': data.length

                            }).end(Buffer.from(data, 'binary'));
                        }
                    });
    } catch (e) {
        console.error(e);
        res.render('error.ejs');
    }
});

Your get file method

async function getFile(fileURL) {
    const url = fileURL;
    console.log(url);
    const newFileName = '/pdf_files/' + genID() + '.pdf';
    const file = fs.createWriteStream('.' + newFileName);
    // this await changes it all. This way you are waiting for the http request to be done. Then you return the name. 
    await https.get(url, function (response) {
        response.pipe(file);
        file.on('finish', function () {
            file.close();
        });
    });
    return newFileName;
}

Let me know if that helps :)

about 4 years ago · Juan Pablo Isaza Relatório

0

You have to wait for writing file done before return (using a Promise to wrap functions that have callback like code below), you are not waiting so in the next flow content of file may be empty.

async function getFile(fileURL) {
        return new Promise(
            (resolve, reject) => {
                const url = fileURL;
                console.log(url);
                const newFileName = '/pdf_files/' + genID() + '.pdf';
                const file = fs.createWriteStream('.' + newFileName);
    
                https.get(url, function (response) {
                    file.on('finish', function () {
                        file.close();
                        resolve(newFileName);
                    });
                    response.pipe(file);
                });
            });
    }
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda