Search code examples
javascriptnode.jsunzip

Unzip and process files in Node.js


I can't find what I am doing wrong here. I'm trying to unzip the files then go though them creating a new HTML in each folder and also renaming the image files.

I tested it and the script is waiting to unzip the files before go though them, but I'm always getting the following error:

(node:3656) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, scandir 'D:\Sites\rename-files\files\cloud'
[0]     at Object.readdirSync (fs.js:955:3)
[0]     at processDirectories (D:\Sites\rename-files\src\controllers\goDirs.js:8:12)
[0]     at goDirs (D:\Sites\rename-files\src\controllers\goDirs.js:31:5)
[0]     at createBanners (D:\Sites\rename-files\src\controllers\RenameController.js:18:33)
[0]     at processTicksAndRejections (internal/process/task_queues.js:97:5)

Here are my files:

RenameController.js

const unzipFiles = require('./unzipFiles')
const goDirs = require('./goDirs')

const RenameController = {

    async root(req, res) {
        res.send('hello root!');
    },

    async createBanners(req, res) {
        const { name, link, template } = req.body
        const { filename } = req.file
        const projectName = name.replace(' ','-')        

        try{
            const unzipPath = await unzipFiles(projectName, filename)
        
            const files = await goDirs(
                                    unzipPath,
                                    projectName, 
                                    template, 
                                    link
                                )

            return res.json(JSON.stringify(files))

        } catch(err){
            return res.json(err)
        }
    }
}
module.exports = RenameController

unzipFiles.js

const fs = require('fs')
const path = require('path')
const unzipper = require('unzipper')

const unzipFiles = (projectName, filename) => {
    const zipFile = path.join(__dirname, `../../files/${filename}`)
    const unzipPath = path.join(__dirname, `../../files/${projectName}`)
   
    return new Promise( (resolve, reject) => {
        fs.createReadStream(zipFile)
            .pipe(unzipper.Extract({ path: unzipPath }))
            .on('close', resolve(unzipPath))
    })
}

module.exports = unzipFiles

goDirs.js

const fs = require('fs')
const path = require('path')
const createHtml = require('./createHtml')
let bannerFiles = []

const goDirs = (directory, projectName, template, link) => {
    const processDirectories = async (directory, projectName, template, link) => {
        fs.readdirSync(directory).forEach(function(file){
            const absolute = path.join(directory, file)
            let filename = ''

            if(fs.lstatSync(absolute).isDirectory()){
                createHtml(file, projectName, template, link)
                return processDirectories(absolute, projectName, template, link)
            } else {
                if (file.indexOf('background') >= 0) filename = 'background.jpg'
                else if (file.indexOf('copy') >= 0) filename = 'copy.png'
                else if (file.indexOf('cta') >= 0) filename = 'cta.png'
                else if (file.indexOf('logo') >= 0) filename = 'logo.png'

                fs.rename(
                    absolute,
                    absolute.replace(file, filename),
                    () => {}
                )                    
                bannerFiles.push(absolute)
            }
        })
    }

    processDirectories(directory, projectName, template, link)

    return new Promise((resolve, reject) => {
        bannerFiles.length != 0 ? resolve(bannerFiles) : reject()
    })
}

module.exports = goDirs

Thanks!!


Solution

  • Apparently, you need to treat the case of a rejection of the processDirectories Promise in the goDirs.js.

        processDirectories(directory, projectName, template, link)
    
    

    try to .catch(...) this ☝️ call to your async method. Like this:

        processDirectories(directory, projectName, template, link).catch(/* your error treatment code */)