Не удается заставить работать обработку ошибок multer filefilter

Играю с загрузкой файлов в Node.js / Multer.

У меня работает хранилище и лимиты. Но теперь я играю с файловым фильтром, чтобы просто запретить некоторые файлы mimetype вот так:

fileFilter: function (req, file, cb) {
 if (file.mimetype !== 'image/png') {
  return cb(null, false, new Error('goes wrong on the mimetype'));
 }
 cb(null, true);
}

Когда загружается файл не в формате PNG, он его не принимает. Но это также не вызовет if(err)

Когда файл слишком большой, он вызывает ошибку. Так или иначе, мне нужно сгенерировать ошибку и на filefilter, но я не знаю, как это сделать, и думаю, что new Error неверно.

Итак, как я должен генерировать ошибку, если файл неправильный? Что я делаю неправильно?

Полный код:

var maxSize = 1 * 1000 * 1000;

var storage =   multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, 'public/upload');
  },
  filename: function (req, file, callback) {
    callback(null, file.originalname);
  }
});


var upload = multer({
   storage : storage,
   limits: { fileSize: maxSize },
   fileFilter: function (req, file, cb) {
     if (file.mimetype !== 'image/png') {
       return cb(null, false, new Error('I don\'t have a clue!'));
     }
     cb(null, true);
   }

 }).single('bestand');


router.post('/upload',function(req,res){
    upload(req,res,function(err) {
        if(err) {
              return res.end("some error");
        }
    )}
)}

person Merijn de Klerk    schedule 27.01.2016    source источник
comment
Ищу этот мультер ({storage, filteFilter ...}) спасибо.   -  person Aljohn Yamaro    schedule 23.12.2019


Ответы (4)


Функция fileFilter имеет доступ к объекту запроса (req). Этот объект также доступен в вашем роутере.

Поэтому в fileFitler вы можете добавить свойство с ошибкой проверки или список ошибок проверки (вы можете загрузить много файлов, и некоторые из них могут пройти). И в роутере вы проверяете, существует ли свойство с ошибками.

в фильтре:

fileFilter: function (req, file, cb) {
 if (file.mimetype !== 'image/png') {
  req.fileValidationError = 'goes wrong on the mimetype';
  return cb(null, false, new Error('goes wrong on the mimetype'));
 }
 cb(null, true);
}

в роутере:

router.post('/upload',function(req,res){
    upload(req,res,function(err) {
        if(req.fileValidationError) {
              return res.end(req.fileValidationError);
        }
    )}
)}
person Krzysztof Sztompka    schedule 28.01.2016
comment
Ааа, звучит хорошо. Я проверю это позже сегодня, когда вернусь домой. Спасибо! - person Merijn de Klerk; 04.02.2016
comment
если вы измените расширение exe файла на png, вы можете обмануть multer. - person Jitendra Pancholi; 18.12.2016
comment
Конечно. Всегда важно то, чего вы хотите. Иногда достаточно проверить ext, и нам все равно, что с ним будет. Иногда вы хотите проверить первые байты файла, чтобы убедиться, какой у него настоящий тип - например, когда вам нужно что-то сделать с этим файлом. Но что делать, если файл поврежден. В этом случае вам также необходимо проверить файл полностью. Как инженеры, мы обязаны выбирать лучшие инструменты для каждого сценария. - person Krzysztof Sztompka; 18.12.2016

Вы можете передать ошибку в качестве первого параметра.

multer({
  fileFilter: function (req, file, cb) {
    if (path.extname(file.originalname) !== '.pdf') {
      return cb(new Error('Only pdfs are allowed'))
    }

    cb(null, true)
  }
})
person Gabriel Hidalgo    schedule 06.02.2019

Измените fileFilter и передайте ошибку функции cb:

function fileFilter(req, file, cb){
   if(file.mimetype !== 'image/png'){
       return cb(new Error('Something went wrong'), false);
    }
    cb(null, true);
};
person Ömürcan Cengiz    schedule 26.09.2019
comment
Я показываю шаблон fileuploaded.hbs при успешной загрузке с помощью res.render ('fileuploaded'). Есть ли способ показать ошибку в шаблоне вместо того, чтобы просто отображать общую страницу ошибки браузера? - person Paul Morris; 29.04.2020

Обратный вызов fileFilter должен быть:

fileFilter: async (req, file, cb) => {
    if (file.mimetype != 'image/png') {
        cb(new Error('goes wrong on the mimetype!'), false);
    }
    cb(null, true);
}

Обработка ошибок в запросе:

  • ошибка доступа к Multer с использованием MulterError
const multer = require("multer");

router.post('/upload', function(req, res) {
    upload(req, res, function(err) {

        // FILE SIZE ERROR
        if (err instanceof multer.MulterError) {
            return res.end("Max file size 2MB allowed!");
        }

        // INVALID FILE TYPE, message will return from fileFilter callback
        else if (err) {
            return res.end(err.message);
        }

        // FILE NOT SELECTED
        else if (!req.file) {
            return res.end("File is required!");
        }
 
        // SUCCESS
        else {
            console.log("File uploaded successfully!");
            console.log("File response", req.file);
        }

    )}
})
person turivishal    schedule 20.12.2020