NodeJS Multer unable to catch eroor - javascript

How do I catch the error invoked and return a res status msg? I am unable to catch any error in userController.uploadFile and if I tried to do a upload(req,res (err) in the routes.post, req is not defined.
var storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, url);
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
}).single('file');
let upload = multer({
storage: storage,
limits: { fileSize: maxSize },
fileFilter: (req, file, cb) => {
console.log(file);
if (file.mimetype !== 'image/jpeg' || file.mimetype !== 'image/png') {
return cb(new Error('Only jpeg images allowed'))
}
cb(null, true)
}
});
routes.post('/fileupload', upload, userController.uploadFile);

I think we can get this to work with a little tweaking. I've made these changes and tested with a few images.
Your user controller will look a little different, but something like this should work.
I've updated to pass any file too large error to the controller, again this will be in the req.uploadError property, so you can handle as you like.
const userController = {
uploadFile(req, res) {
if (req.uploadError) {
res.status(400).send("An error occurred - " + req.uploadError.message);
} else {
res.status(201).send("All good");
}
}
}
var storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, url);
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
});
let upload = multer({
storage: storage,
limits: { fileSize: maxSize },
fileFilter: (req, file, cb) => {
console.log(file);
if (file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png') {
cb(new Error('Only jpeg or png images allowed'));
} else {
cb(null, true);
}
}
}).single('file');
routes.post('/fileupload', (req, res, next) => {
upload(req, res, err => {
req.uploadError = err;
next();
})
}, userController.uploadFile);

Related

How upload buffer files in array to express server?

I have array with buffer files. I have been trying upload buffers to express server using multer for whole day.
Problem is my files pass by req.body.image. But multer finds files from req.files. Multer can't found files and alerted error. How fix this problem?
Front End code:
let UserPhoto = ["data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAA"];
let formData = new FormData();
for (let i = 0; i < userPhoto.length; i++) {
formData.append("files", userPhoto[i]);
}
axios
.post(`v0/photo/${id}/User`, formData, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
}
Back End code:
const fileFilter = (req, file, cb) => {
if (file.mimetype.substr(0, 6) === "image/") {
cb(null, true);
} else cb(new ErrorCatcher("Зөвхөн зураг upload хийнэ үү.", 400), false);
};
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, director);
},
filename: (req, file, cb) => {
cb(null, Date.now() + "." + file.mimetype.split("/")[1]);
},
});
const upload = multer({
storage: storage,
limits: { fileSize: process.env.IMAGE_MAX_SIZE },
fileFilter: fileFilter,
});
//authorize,
// permission("user", "operator", "manager", "admin"),
router
.route("/:objectId/:objectType")
.post(upload.array("files", 8), createImageConnect);
I was using formData. Result was same.

How to Delete files after certain time?

Here is the code which allows to upload files. Which I want to delete If lastClick (defined at download.js) is 1 day.
let storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const uniqueName = `${Date.now()}-${Math.round(Math.random() * 1E9)}${path.extname(file.originalname)}`;
cb(null, uniqueName)
}
});
let upload = multer({
storage: storage,
limits: {
fileSize: 16106119114
},
}).single('file'); //100mb
router.post('/', (req, res) => {
upload(req, res, async (err) => {
if (err) {
return res.status(500).send({
error: err.message
});
}
const file = new File({
guploadBy: req.user.googleId,
fuploadBy: req.user.facebookId,
tuploadBy: req.user.twitterId,
uploaderName: req.user.name,
fileName: req.file.filename,
originalName: req.file.originalname,
provider: req.user.provider,
path: req.file.path,
fileSize: Math.round((req.file.size * (1 / 1000000))),
adultContent: req.body.select,
uuid_s: shortid.generate(),
uuid_d: uuidv4()
});
const response = await file.save();
});
Below I have written code to delete the files after (lastClick + 1 Day) and this should run every 1 min.
setInterval(findRemoveSync.bind(this,__dirname + '/uploads', {age: {seconds: 60}}), req.file.lastClick+86,400,000)
Can anyone tell me whats wrong with my code?

How to read stored file using Multer disk storage option (NodeJs)?

I am able to store images in my local disk storage using multer successfully but while using GET method, it throws "Cannot GET /uploads/image-1547436792386" error. I have provided my image-upload.js code below:
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now());
}
});
const upload = multer({ storage: storage });
module.exports = upload;
Service.ts:
const imageUpload = require('../services/image-upload');
const singleUpload = imageUpload.single('image');
module.exports = function(app) {
app.post('/api/image-upload', auth.jwtRefreshToken, imageUploadRoute);
};
function imageUploadRoute(req, res) {
const userId = req.userId;
if (typeof userId !== 'string') {
return res.status(422).json({message: 'Error in UserId'});
}
singleUpload(req, res, function(err) {
if (err) {
return res.status(422).send({errors: [{title: 'Image Upload error', detail: err.message}]});
}
User.findOne({_id: userId})
.then((user) => {
console.log(req.file);
user.profileImage = req.file.path;
return user.save()
.then(() => {
return res.status(200).send({message: 'Image Uploaded Successfully'});
})
.catch(() => {
return res.status(500).send({message: 'Error in uploading image'});
});
})
.catch(() => {
return res.status(500).send({message: 'UserId not found'});
});
});
}
Where is your GET API implementation?.Anyway, below code worked for me to download the files. Please try this.
app.get("/download/:name(*)", function (req, res, next) {
var file = req.params.name;
var path = '/yourFileLocation' + '/' + file;
res.download(path, file, function (err) {
if (err) {
res.status(500).send({ "error": 'Unexpected error occured.' });
} else {
res.send({ "message": 'success' });
}
});
});

can't change name to uploaded file using multer

I am trying to change the name of the image im uploading to the server using multer which gives the file a random name.
I user multer.diskStorage method to do so as described in the documentation but it keeps saving the file with random names
CODE:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null,'./uploads/')
},
fileName: (req,file,cb) => {
cb(null, file.originalname)
}
})
const upload = multer({storage: storage})
router.post('/', upload.single('carImage') ,(req, res) => {
res.send(req.file);
}
RESPONSE :
{
fieldname: 'carImage',
originalname: 'testOCR8.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './uploads/',
filename: '229f70c20e5550dbe638db49791ef17d',
path: 'uploads/229f70c20e5550dbe638db49791ef17d',
size: 1712380
}
im uploading to the server using multer which gives the file a random name
You made a typo. It is filename not fileName. This is the standard behavior as per the docs.
filename is used to determine what the file should be named inside the folder. If no filename is given, each file will be given a random name that doesn't include any file extension.
So, your code should be
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null,'./uploads/')
},
filename: (req,file,cb) => { // notice the change 'filename'
cb(null, file.originalname)
}
});
const upload = multer({storage: storage});
Try a different approach for using StorageMulter. Try the following -
var StorageMulter = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "./temp");
},
filename: function(req, file, callback) {
var uploadFileName = "x.jpg"; //Manipulate this variable accordingly
callback(null, uploadFileName);
}
});
var upload = multer({
storage: StorageMulter
});
app.post("/api/uploaddocument", function(req, res) {
upload(req, res, function(err) {
if (err) {
return res.end("Something went wrong!"+ err);
}
});
});

Encrypt the uploaded file before saving to disk using Node.js

Currently, I am using multer library to save files on File system. This application is using Node and Express.
I can save the file first on server and then encrypt it. Later on delete the unencrypted file. However, I do not want to add unencrypted file on server directly. So, I am looking for a way to encrypt the incoming file from the front end and then save it to disk.
const defaultFolder = 'upload';
const filePath = resolveHome(process.env.FILE_STORAGE_LOCATION || defaultFolder);
const key = 'test';
const cipher = crypto.createCipher('aes-256-cbc', key);
const decipher = crypto.createDecipher('aes-256-cbc', key);
const upload = multer({
storage: multer.diskStorage({
destination: filePath,
filename: (req, file, cb) => {
const parts = file.originalname.split('.');
const ext = parts.pop();
const name = parts.join('.');
cb(null, name + '-' + Date.now() + '.' + ext);
},
}),
}).single('file');
app.post('/upload', (req, res) => {
upload(req, res, err => {
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.filename,
});
});
});
I tried to use crypto library to encrypt the file but it's not working. I believe the req.cipher is invalid as I would normally use req.file to get reference to the file.
app.post('/upload', (req, res) => {
upload(req, res, err => {
output = fs.createWriteStream(filePath + '/' + req.file.originalname);
req.pipe(cipher).pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
if (err) {
return res.status(400).send({
error: 'The request was invalid',
fileName: req.file.originalname,
});
}
return res.status(200).send({
fileName: req.file.originalname,
});
});
});
I had tried to just write file without using cipher and file was empty. Adding this information in case it helps.
req.pipe(output).on('finish', () => console.log('Encrypted file written on disk'));
Can you try this
app.post('/upload', function(req, res) {
upload(req, res, function(err) {
var fileName = req.file.destination +"\\"+ req.file.filename
var input = fs.createReadStream(fileName);
var output = fs.createWriteStream(fileName + ".enc");
input.pipe(cipher).pipe(output);
output.on('finish', function() {
fs.unlink(fileName, (err) => {
if (err) throw err;
console.log('Encrypted file written to disk!');
res.end('Encrypted file written to disk!')
});
});
})
})

Categories

Resources