Skip to content

Multer writes file with zero size if originalname changes in the storage.filename prop. #1365

@skyshy0707

Description

@skyshy0707

Hello, dear! Odd multer behaviour is occured. If such filename are existed in directory then i set a new filename via generateUserFileName function which used as a tool for filename property of my multer storage. What i totaly doing wrong when i use async fs to check if the file exist? Because i don't have problems with multer that used to change originalname -> some newName in the another project without fs tool checkings

const fs = require('node:fs')
const multer = require('multer')
const path = require('node:path')

const FILE_UPLOAD_PATH = '/code/uploads'
const UPDATE_FILE_URL = /\/file\/update\/[\d]+/

async function generateUserFileName(originalname, request){

    const userId = request.userId
    const fileId = request.params?.id || null
    const url = request.url
    const file = await dao.getFile(fileId, userId)
    const fileDir = path.resolve(FILE_UPLOAD_PATH, userId.toString())
    const filePath = path.resolve(fileDir, originalname)

    if (file){
        const oldFileName = path.resolve(fileDir, file.name)
        if (url.match(UPDATE_FILE_URL)){
            try{
                await fs.promises.access(oldFileName)
                await fs.promises.unlink(oldFileName)
            }
            catch (error){
                //pass
            }
        }
    }

    try{ 
        await fs.promises.access(filePath) //if filename is exist then it generates a new name:
        return path.parse(originalname).name + `_${Date.now()}` + path.extname(originalname)
    }
    catch (error){
        return originalname //if file is not exist then filename is the same as it is in request.originalname
    }
}

const storage = multer.diskStorage({
    destination: async (request, file, callback) => {
        console.log(`Userid: ${request.userId}`)

        const fileDir = path.resolve(FILE_UPLOAD_PATH, request.userId.toString())

        try{
            await fs.promises.access(fileDir)
        }
        catch (error){
            await fs.promises.mkdir(path.resolve(fileDir))
        }
        callback(null, fileDir)
    },

    filename: async (request, file, callback) => {
        const fn = await generateUserFileName(file.originalname, request)
        
        console.log(`File name ${fn} was generated successfully`)// Always, here my filename is generated successfully
        callback(null, fn)
    }
})

const upload = multer({ 
    storage: storage
})
const uploadStorage = upload.single('file')


module.exports = {
    uploadStorage,
    deleteFile
}

If my filename is differ from originalname in the cases when such file is exist, then multer wrire empty file with zero size.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions