multer
multer copied to clipboard
Multer diskStorage destination errors on production environment
Hello,
On development environment code below works properly but on production nothing works.When I opened logs there are this error: Error OccuredError: ENOENT: no such file or directory, open 'public/images/8c3f666974_kiwi.png'.2 days I am trying to resolve it but... no result I try many things read many articles but nothing ... What is the problem?I read all multer documentation and I think I am implementing it properly?
This is code:
const express = require("express");
const router = express.Router();
const multer = require('multer');
const db = require("../connection/databaseConn");
const Product = require("../models/Product");
const encryption = require("../encryption/encryption");
const path = require('path')
let storage;
let upload;
router.get("/upload",(req,res)=>{
res.render("upload");
});
let imagesNames = [];
new Promise((resolve, reject)=>{
resolve(
storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null,"public/images/")
},
filename: function (req, file, cb) {
let imageId = encryption.generateId();
let imageNameWithId = imageId.substr(0,10);
imagesNames.push({name:imageNameWithId,id:imageId});
let fileName = "" + imageNameWithId + "_" + file.originalname;
cb(null, fileName)
}
}))
}).then((storage)=>{
upload = multer({storage:storage}).any();
})
router.post('/upload', function(req, res) {
upload(req, res, function(err) {
if(err) {
console.log('Error Occured' + err);
return;
}
let files = req.files;
Product.findById(req.session.productId).then((p)=>{
for(let i = 0; i < files.length;i++){
p.images.push({imageId:imagesNames[i].id,imageName :"/static/images/" + imagesNames[i].name + "_" + files[i].originalname});
}
p.save();
}).then(()=>{
req.session.addMessage = "Product created!";
res.redirect("/categoriesLoad");
});
})
});
module.exports = router;
Does the directory public/images
exist?
Yes exist, images dir is in public dir.Now I change my code to this below, but now it gives me "Internal server error: http://s1356.photobucket.com/user/acho999/media/Internal%20server%20error_zpsrmx4heor.jpg.html?sort=3&o=0
But on development again everything is working.I have images on file system and in my product object.
const express = require("express");
const router = express.Router();
const multer = require('multer');
const db = require("../connection/databaseConn");
const Product = require("../models/Product");
const encryption = require("../encryption/encryption");
const path = require('path');
router.get("/upload",(req,res)=>{
res.render("upload");
});
let imagesNames = [];
const multerConfig = {
storage : multer.diskStorage({
destination: function (req, file, next) {
next(null,"public/images/")
},
filename: function (req, file, next) {
let imageId = encryption.generateId();
let imageNameWithId = imageId.substr(0,10);
imagesNames.push({name:imageNameWithId,id:imageId});
let fileName = "" + imageNameWithId + "_" + file.originalname;
next(null, fileName)
}
})
};
router.post('/upload',multer(multerConfig).any(), function(req, res) {
let files = req.files;
Product.findById(req.session.productId).then((p)=>{
for(let i = 0; i < files.length;i++){
p.images.push({imageId:imagesNames[i].id,imageName :"/static/images/" + imagesNames[i].name + "_" + files[i].originalname});
}
p.save();
}).then(()=>{
req.session.addMessage = "Product created!";
res.redirect("/categoriesLoad");
});
});
module.exports = router;
next(null,"public/images/")
Could you try returning an absolute path here? Something like:
next(null, path.join(__dirname, 'public/images'))
Hi, thanks for helping me! I try by this way but on development environment it gives me: Error: ENOENT: no such file or directory, open 'c:\Users\Angel\Documents\Наков\JSweb\NodeAndExpress\projects\project\routes\public\images\e1ada8c985_kiwi.png'
because directory public is in directory project.In path above it search public directory in routes directory, and that is wrong. In screenshot below on left side is my Upload.js file which is on routes dir and __dirname returns path to this dir, an I think this is reason __pathname not working in this case. http://s1356.photobucket.com/user/acho999/media/error_zpsysmzjizx.jpg.html. And there is my public dir and images dir (ignore dropzone files I don't use them). Without __dirname everything works on development.When I upload image it shows in images dir.But this is only on development, on production trows error.
adjust the path to match relative to the file that holds the logic:
next(null, path.join(__dirname, '../public/images'))
Thanks for suggestion, but again on development it works and on production return "Internal server error". As you can see on image below, in green color ,on left side, is image which I add on development environment in directory images: http://s1356.photobucket.com/user/acho999/media/dev-env_zpshjjtaivd.jpg.html. And as I wrote above on prod environment doesn't work... this is take me yet 5 days at least...
Here is screenshot of heroku logs.On the bottom where is /upload path have error, quality is not very good: http://s1356.photobucket.com/user/acho999/media/logs_zps55htwmar.jpg.html
This is error on /upload path, from heroku logs:
2018-10-03T14:29:07.566481+00:00 heroku[router]: at=info method=POST path="/upload" host=enigmatic-falls-17964.herokuapp.com request_id=74417b65-3e3d-4b70-941e-c3199325bf6c fwd="46.55.152.189" dyno=web.1 connect=0ms service=9884ms status=500 bytes=404 protocol=https 2018-10-03T14:29:07.565769+00:00 app[web.1]: Error: ENOENT: no such file or directory, open '/app/public/images/5a901a8328_IMG_20181003_142936.jpg'
Same error. Any fix?
Error: ENOENT: no such file or directory, open '/app/public/images/5a901a8328_IMG_20181003_142936.jpg'
This means that the directory /app/public/images
doesn't exist, you have to create it prior to putting files in it...
Same issue, did you figure it out?
After research, in your case you can't upload images to the server because I think you are using server-less project so from the best practices upload your images to aws s3. please checkout the following https://www.freecodecamp.org/news/express-js-and-aws-lambda-a-serverless-love-story-7c77ba0eaa35/
Same issue. Did someone figured out?
Try using
destination: require.main?.path + "/" +" public/images/ "
(tested using "multer": "^1.4.2" , in typescript project)
Using destination directly inside storage object without callback worked for me.
destination: path.join(__dirname, '../public/images'),
destination: require.main?.path + "/" +" public/images/ "
This is working very well
Try using
destination: require.main?.path + "/" +" public/images/ "
(tested using "multer": "^1.4.2" , in typescript project)
This works very well, thank you.