How do i produce multer error message in my postman - mysql

Im trying to res.status.send a multer error message to postman when my file image exceeds 1MB. But when i try to run my code it only gives me this entire chunk of error message. I just want to get the error message itself(LIMIT_FILE_SIZE).Is there any way to achieve this?
IMAGE HERE
My current app.js:
var multer = require('multer');
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploads');
},
filename: function(req, file, callback) {
callback(null, path.basename(file.originalname));
}
})
const upload = multer({
dest: storage,
storage: storage,
limits: {
fileSize: 1024 * 1024
},
fileFilter: function(req, file, callback, error) {
var ext = path.extname(file.originalname);
var error_msg = error instanceof multer.MulterError
if(ext !== '.jpg') {
req.fileValidationError = "Not a jpg file!";
return callback(null, false, req.fileValidationError);
}
if(error_msg) {
return callback(null, false, new MulterError('LIMIT_FILE_SIZE'))
}
callback(null,true)
}
});
app.post("/upload",upload.single('name'),(req,res,next) => {
if(req.fileValidationError) {
res.status(500).send({message:req.fileValidationError});
}
else {
if(error.code === 'LIMIT_FILE_SIZE') {
req.fileSizeError = "Image more than 1MB!"
res.status(500).send({message:req.fileSizeError});
}
else {
console.log('File Received!');
console.log(req.file);
var sql = "INSERT INTO `file`(name,description,type,size) VALUES('" + req.file.filename + "', '" + (req.file.encoding + "_" + req.file.destination + "_" + req.file.path)+ "', '" + req.file.mimetype + "', '" + req.file.size + "')";
db.query(sql, (error, results) => {
console.log('Inserted Data!');
});
const message = "Successfully Uploaded!"
res.status(200).send({message:message, file_details:req.file})
}
}
})

Multer delegates the error to Express which is the standard way of throwing errors in express. To catch a specific error, you can use the multer upload middleware inside the route callback. This is the method as given by multer's documentation, also mentioned by #Mattia Rasulo
router.post('/image', function (req, res, next) {
upload.single('image')(req, res, function (error) {
if (req.fileValidationError) {
res.status(500).send({ message: req.fileValidationError });
}
else {
if (error) {
res.status(500).send({ message: error.code === 'LIMIT_FILE_SIZE' ? "Image more than 1MB!" : error.message });
}
else {
console.log('File Received!');
console.log(req.file);
var sql = "INSERT INTO `file`(name,description,type,size) VALUES('" + req.file.filename + "', '" + (req.file.encoding + "_" + req.file.destination + "_" + req.file.path)+ "', '" + req.file.mimetype + "', '" + req.file.size + "')";
db.query(sql, (error, results) => {
console.log('Inserted Data!');
});
const message = "Successfully Uploaded!"
res.status(200).send({message:message, file_details:req.file})
}
}
});
});

Multer just sends the error to your global error middleware so you just catch it and check upon what error is:
if(err.message === 'file too large') [change the message as you need].
This is how I've handled your exact same issue!
https://www.npmjs.com/package/multer#error-handling

Related

TypeError: Cannot read property 'filename' of undefined--multer

I am currently facing a similar problem to this post. I managed to resolve my initial issue after referencing solutions posted there. However, when i tried to post a image that is less than 1MB and is a jpg formatted image( which i managed to do before the editing), it now fails and state that TypeError: Cannot read property 'filename' of undefined.
My app.js code:
const upload = multer({
dest: storage,
storage: storage,
limits: {
fileSize: 1024 * 1024
},
fileFilter: function(req, file, callback,error) {
var ext = path.extname(file.originalname);
var error_msg = error instanceof multer.MulterError;
if(ext !== '.jpg') {
req.fileValidationError = "Not a jpg file!";
return callback(null, false, req.fileValidationError);
}
if(error_msg) {
req.fileSizeError = "Image more than"
return callback(null, false, req.fileSizeError)
}
callback(null,true)
}
});
app.post("/upload", function (req, res, next) {
upload.single('name')(req, res, function (error) {
if(req.fileValidationError) {
res.status(500).send({message:req.fileValidationError});
}
else {
if(error.code === 'LIMIT_FILE_SIZE') {
req.fileSizeError = "Image more than 1MB!";
res.status(500).send({message:req.fileSizeError});
}
else {
console.log('File Received!');
console.log(req.file);
var sql = "INSERT INTO `file`(name,description,type,size) VALUES('" + req.file.filename + "', '" + (req.file.encoding + "_" + req.file.destination + "_" + req.file.path)+ "', '" + req.file.mimetype + "', '" + req.file.size + "')";
db.query(sql, (error, results) => {
console.log('Inserted Data!');
});
const message = "Successfully Uploaded!"
res.status(200).send({message:message, file_details:req.file})
}
}
})
})
The array does only contain objects, not the filename property. The first object in the array does have the filename property. Select the first and only item in it using req.files['image'][0].filename or req.files[0].filename and it should work.
It looks like the error handling isn't right, during file saving in particular; in which the resulting errors are not being handled. For example, try deleting the destination directory "uploads" and then upload a file, TypeError: Cannot read property 'filename' of undefined will be thrown again!
To resolve this and to determine what exactly is the error, you should handle the upload.single() error callback.
app.post("/upload", function (req, res, next) {
upload.single('name')(req, res, function (error) {
if (error) {
console.log(`upload.single error: ${error}`);
return res.sendStatus(500);
}
// code
})
});
Make sure your sending in your request header "Content-Type": "multipart/form-data"
Bingo!! resolved this
For me I was just sending the image name and not the object (const file = event.target.files[0]; file in this case).
Hope this help you:)
Add this enctype="multipart/form-data" in your form tag its like:
<form action="/admin/banner/update?id={{bannerEdit._id}}" enctype="multipart/form-data" method="post">

How to save data to mysql server with Node.js

I am currently trying to build an application for my project.
It is my first time programming as well as using node.js
I have successfully connected node.js with mysql and was able to save data to mysql server.
However, some data that I want to save is declared as undefined
currently my code looks like this
imap.once('ready', function() {
openInbox(function(err, box) {
if (err) throw err;
imap.search([ 'UNSEEN', ['SINCE', 'December 20, 2018'] ], function(err, results) {
if (err) {
console.log('you are already up to date');
}
//var f = imap.fetch(results, {markSeen: true, bodies: ''});
var f = imap.fetch(results, {bodies: ''});
f.on('message', function(msg, seqno) {
var prefix = '(#' + seqno + ') ';
msg.on('body', function(stream, info) {
simpleParser(stream, (err, mail) => {
con.connect(function(err) {
console.log("Connected!");
var sql = "INSERT INTO scrap (reply_to, content) VALUES ('" + mail.from.text + "', '" + mail.subject +"')";
con.query(sql, function (err , result) {
});
});
console.log(mail.from);
// console.log(mail.from.text);
// console.log(mail.subject);
// console.log(mail.text);
});
the Console.log will fetch information like this
{ value:
[ { address: 'xxx#gmail.com', name: 'NAME' } ],
html:
'NAME <xxx#gmail.com>',
text: 'NAME ' }
I would like to know how to fetch email and name separately.
I have tried console.log(mail.from.address) or (mail.from.mailto) but it returns undefined
try
mail.from.value[0].address // fetch email
mail.from.value[0].name //fetch name

express + mysql : clean code for complex queries

I am using express with mysql for my api.
This code works fine :
exports.addAuthor = function(req, res, next) { // POST /authors {{{
let sqlquery = '';
let a = checkAuthor(req.body);
if(!a.valid) {
var myerr = new Error(a.msg);
myerr.status = 400;
return next(myerr);
}
//
myPool.getConnection(function(err, connection) {
if (err) { return next(err); }
// check if exists first
sqlquery = 'SELECT COUNT(*) AS nb FROM authors';
sqlquery += ' WHERE name = "' + a.name + '" AND firstname = "' + a.firstname + '";';
connection.query(sqlquery, function(err, rows) {
if (err) {
connection.release();
return next(err);
} else {
if (rows[0].nb > 0) {
connection.release();
let myerr = new Error('This author already exists !');
myerr.status = 400;
return next(myerr);
} else {
sqlquery = 'INSERT INTO authors (name, firstname)';
sqlquery += ' VALUES ("' + a.name + '","' + a.firstname + '")';
connection.query(sqlquery, function(err, rows) {
connection.release();
if (err) { return next(err); }
if (rows.affectedRows) {
res.json({name: a.name, firstname: a.firstname, id: rows.insertId});
}
});
}
}
});
});
}; // }}}
First, I would like to reuse the code to get the id of the author, if it exists, so define one function for that.
Secondly I would like to write simpler and cleaner code as I imagine more complex code with several requests to the DB for future cases. (12 lines only to check if author exists !)
I know it has to deal with asynchronous nature of the Mysql queries.
I read many things but I am still no able to write proper code to acheive that.
Thanks to point me to right way to manage not so simple case.
JPM
I think I succeeded to make work some code that was not working yesterday !
I do not know yet if it is the best way however.
I took some piece of code somewhere but I do not remember where (probably here).
Here it is :
const execQuery = (sql, params) => new Promise((resolve, reject) => { // {{{
myPool.getConnection(function(err, connection) {
if (err) {
reject(err);
} else {
connection.query(sql, function(err, rows) {
connection.release();
if (err) {
reject(err);
} else {
resolve(rows);
}
})
}
});
}); // }}}
async function getIDAuthor(a) { // {{{
sqlquery = 'SELECT id FROM authors';
sqlquery += ' WHERE name = "' + a.name + '" AND firstname = "' + a.firstname + '"';
if(a.id) { // case update name of known author
sqlquery += ' AND id <> ' + a.id;
}
try {
rows = await execQuery(sqlquery);
if(rows.length>0) {
return rows[0].id;
} else {
return 0;
}
} catch (error) {
return -1;
}
} // }}}
exports.addAuthor = async function(req, res, next) { // POST /authors {{{
let sqlquery = '';
let a = checkAuthor(req.body); // {{{
if(!a.valid) {
var myerr = new Error(a.msg);
myerr.status = 400;
return next(myerr);
} // }}}
let ide = await getIDAuthor(a);
if(ide>0) {
let myerr = new Error('This author already exists !');
myerr.status = 400;
return next(myerr);
}
sqlquery = 'INSERT INTO authors (name, firstname)';
sqlquery += ' VALUES ("' + a.name + '","' + a.firstname + '")';
try {
rows = await execQuery(sqlquery);
if (rows.affectedRows) {
res.json({name: a.name, firstname: a.firstname, id: rows.insertId});
}
} catch (error) {
return next(error);
}
}; // }}}
I have not yet checked all possible errors.
Feel free to advise me or correct me if needed.
I took code and ideas from https://nemethgergely.com/error-handling-express-async-await/
So it looks now like this:
exports.addAuthor = asyncMiddleware(async function(req, res, next) { // POST /authors {{{
let sqlquery = '';
let rows;
//
let a = checkAuthor(req.body);
if(!a.valid) { throw boom.badRequest(a.msg); }
let ide = await getIDAuthor(a);
if(ide>0) { throw boom.badRequest('Cet auteur existe déjà !'); }
//
sqlquery = 'INSERT INTO authors (name, firstname)';
sqlquery += ' VALUES ("' + a.name + '","' + a.firstname + '")';
rows = await execQuery(sqlquery);
if (rows.affectedRows) {
res.json({name: a.name, firstname: a.firstname, id: rows.insertId});
}
}); // }}}
In fact this does not handle all error cases. Forget it. Still at start point. Grrrrrr.

Upload Excel file and download from mysql using Node js

I want to upload Excel sheet and after submit that excel sheet need to insert data into mysql database and same sheet which we upload need to download.
I have tried below code:
Node Service-
function getDetails(req, res) {
var sampleFile, fileInfo = {};
var post = req.body;
var ID= post.id;
var name=post.name
if (!req.files) {
res.send('No files were uploaded.');
return;
}
sampleFile = req.files.fileInputXLSX;
console.log("req.body -- ",req.body);
console.log("Uploaded -- ",sampleFile);
// Get file attributes
var fileId = req.body.fileId;
var fileExtn = sampleFile.name.split(".").pop();
var extractedFilename = sampleFile.name.slice(0, sampleFile.name.lastIndexOf('.'));
var uploadFileName = extractedFilename+'_'+fileId+'.'+fileExtn;
console.log("uploadFileName -- ",uploadFileName);
fileInfo = {
"name": uploadFileName,
"mimetype": sampleFile.mimetype
}
sampleFile.mv(__dirname+'/Myuploads/Details/'+uploadFileName, function(err) {
if (err) {
res.status(500).send(err);
}
else {
// Update file info
var queryString = "INSERT INTO 'details'('id','name') VALUES ('" + ID + "','" + name + "')";
connection.query(queryString, function(err, result) {
if (!err){
var response = [];
response.push({'result' : 'success'});
if (result.length != 0) {
response.push({'data' : result});
} else {
response.push({'msg' : 'No Result Found'});
}
res.setHeader('Content-Type', 'application/json');
res.status(200).send(JSON.stringify(response));
} else {
res.status(400).send(err);
}
});
}
});
}
Controller.js
$scope.MyFunction=function(){
var excelForm = new FormData();
excelForm.append('fileInputXLSX', document.getElementById("fileInputXLSX").files[0]);
console.log("---- excelFile : ", document.getElementById("fileInputXLSX").files[0]);
// End : Get File
$http.post(Data.baseNodeService + "getDetails", {
"newProtocolObj": $scope.newProtocolObj
},headconfig).success(function(data, status, headers, config) {
console.log('Details: success');
excelForm.append('fileId', data);
jQuery.ajax({
url: data.baseNodeService + "getDetails",
type: "POST",
cache: false,
contentType: false,
processData: false,
data: excelForm,
success: function(data) {
console.log("---- upload response : ", data);
$scope.goToTfilePage();
}
});
// End : Upload File
}).error(function(map_data, status, headers, config) {
console.log('Details: error');
console.log('status: ', status, '\nmap_data: ', map_data, '\nconfig: ', config);
});
}
Message is coming in console: No file is uploaded.
Please help with the same.It is not upload the file.It is not able to read the response from node service.
I am new in this help in which manner i need to write.
Edit:I am able to upload the file but how to insert into mysql database??

How do I redirect user to 'home' page after validating his login data with database?

After checking login data (user name and password) I would like to redirect the valid user to home page.
Here is app. post:
app.post('/', function ( req , res) {
req.checkBody('home_user_name', 'User Name is required').notEmpty();
req.checkBody('home_password', 'Password is required').notEmpty();
pool.getConnection(function (error, tempCont) {
if (!!error) {
tempCont.release();
console.log('Error');
}
else {
console.log('Connected!');
function get_role(callback) {
console.log("look here >> " + req.body.home_user_name);
here is query:
tempCont.query('SELECT * from `users` where `user_name` = ? ', [req.body.home_user_name] , function (error, results) {
if (error) callback(null);
callback(results[0].password);
});
}
here is the question how to redirect the valid user to home page? note that it is a function inside function inside app.post:
get_role(function (data) {
if (data == req.body.home_password){
console.log("User Name is " + req.body.home_user_name + " and Password is " + data);
}
else {
console.log("passwords are not identical ");
}
}
);
here is errors validation:
var errors = req.validationErrors();
if (errors) {
res.render('app', { errors: errors });
} else {
console.log("Validation: " + req.body.home_user_name);
}
}
})
})
This is the solution:
res.redirect ('home');