Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch the error when i am using file filter in multer?

I have searched but i couldn't find exact solution..When i uploading image it should allow only jpg,jpeg,gif,png..If any other file it should show message in UI. I have used the following code

var upload = multer({ storage: storage,
 fileFilter: function (req, file, cb) {
        var ext = path.extname(file.originalname);
        if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
             return cb(new Error('Wrong extension type'));
            // if(Error){
            //     console.log("error file type")
            // }

        }
        cb(null, true)
    }

});

If i try to upload pic rather than jpeg,jpg,png,git It showing error ..But how to display as message in my application page itself

Error: Wrong extension type
    at fileFilter (D:\Vishnu\octopus new\app\routes.js:912:24)
    at wrappedFileFilter (D:\Vishnu\octopus new\node_modules\multer\index.js:44:7)
    at Busboy.<anonymous> (D:\Vishnu\octopus new\node_modules\multer\lib\make-middleware.js:114:7)
    at emitMany (events.js:127:13)
    at Busboy.emit (events.js:201:7)
    at Busboy.emit (D:\Vishnu\octopus new\node_modules\busboy\lib\main.js:38:33)
    at PartStream.<anonymous> (D:\Vishnu\octopus new\node_modules\busboy\lib\types\multipart.js:213:13)
    at emitOne (events.js:96:13)
    at PartStream.emit (events.js:188:7)
    at HeaderParser.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\Dicer.js:51:16)
    at emitOne (events.js:96:13)
    at HeaderParser.emit (events.js:188:7)
    at HeaderParser._finish (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:68:8)
    at SBMH.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:40:12)
    at emitMany (events.js:127:13)
    at SBMH.emit (events.js:201:7)

Kindly help me in this issue.. Thanks in Advance

like image 996
Vishnu Avatar asked Jan 30 '26 03:01

Vishnu


2 Answers

I've been struggling with this problem for a while now as well. I thought I had found one solution but it ended up not working that well for me but after enough tinkering and looking around tonight I found an answer that works for me. I hope this helps. I actually found this question while looking around for an answer.

So what I did was created req.fileValidationError in your example as so:

var upload = multer({ 
     fileFilter: function (req, file, cb) {
          let ext = path.extname(file.originalname);
          if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
               req.fileValidationError = "Forbidden extension";
               return cb(null, false, req.fileValidationError);
         }
         cb(null, true);
     }
});

Then in your route you want to check req.fileValidationError with an if statement. If it exists then you know there is a forbidden extension.

Assuming you are using express under the app variable, and you are wanting single images to be sent, it would look something like so:

app.post('/your-upload-route', upload.single("your-input-name-here"), function(req, res) {
     if (req.fileValidationError) {
          // return res.sendFile();
          // or return res.end();
          // or even res.render(); whatever response you want here.
     }
});

I hope this helps! If anyone else has a different way of doing this I'd be happy to update my answer as well as seeing other people's insight.

like image 52
guest1234 Avatar answered Feb 01 '26 02:02

guest1234


Adding to this answer, which works like a charm by the way.

If you want a catch-all for errors that result from a file not accepted by MIME type or because a file was not attached, you can do the following:

Set your FileFilter function to something like this:

const upload = multer({
storage: //storage declaration here,
fileFilter: (req, file, cb) => {
        if (
            !file.mimetype.includes("image/png") &&
            !file.mimetype.includes("image/jpeg")
        ) {
            return cb(null, false);
        }
        cb(null, true);
    }
});

and then in your route or wherever your req, res is scoped, you can catch the error and respond accordingly by checking the req.file variable that normally holds the uploaded file information:

if (!req.file) {
            console.log("No file received or invalid file type");
            return res.status(400).send({
                message: "No file received or invalid file type",
                success: false
            });
}

Without setting a new req variable to hold a ValidationError, you can respond gracefully to the user if they don't provide a valid file.

This works because the FileFilter will successfully filter out a file that doesn't match your validation even without throwing an error in the callback, but instead of throwing an error, it just won't proceed with accepting the file. I don't understand fully why the callback in multer is built that way as the method of throwing errors does not bubble up to your route or controller.

With the above code, however, if the fileFilter does its job, when you check that req.file exists (or doesn't in this case) with if(!req.file){}, you can catch both no-file submissions and failed validation at once without the messy error that gets thrown from fileFilter's callback :)

like image 32
FS_woods Avatar answered Feb 01 '26 00:02

FS_woods



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!