Search code examples
javascriptnode.jsexpresserror-handlingmulter

Catching MulterError


I am trying to return a custom error in Multer if a file exists using a callback. I use "cb(new Error('Flyer already exists'));" if the file exists, but I would like to return the message to the front end, React JS, if the error occurs. The code below is the code that I have in Node JS. I could not use the alternate configuration because other data, like flyerName, from the frontend are returned undefined. The alternative configuration is below. Any explanation or advice will be will help.

Current Code

//----------------------------------------- BEGINNING OF PASSPORT MIDDLEWARE AND SETUP ---------------------------------------------------
const flyerDestination = './routes/Flyers'
const flyerStorage = multer.diskStorage({
  destination: function (req, file, cb){ 
    cb(null, flyerDestination)
  },
  filename: function (req, file, cb){
    if (fs.existsSync(path.join(flyerDestination,file.originalname))) {
      cb(new Error('Flyer already exists'));
    } else {
      cb(null, file.originalname);
    }
  }
});
const flyerUpload = multer({ storage: flyerStorage });
//----------------------------------------- END OF PASSPORT MIDDLEWARE AND SETUP ---------------------------------------------------
router.post('/Flyer_Upload', flyerUpload.array('files'), (req, res) => {
  const flyerName = req.body.flyerName;
  const flyerEventDate = req.body.flyerEventDate;
  const flyerDescription = req.body.flyerDescription;
  const flyerID = Math.floor(Math.random()*90000) + 10000;
  const flyerDirectory = 'http://localhost:3001/Flyers/'

  for (const file of req.files) {
    directory = path.dirname(file.path);
    const flyerUploadedPath = flyerDirectory + file.filename
    
    console.log('flyerName: ' + flyerName);
    console.log('flyerEventDate: ' + flyerEventDate);
    console.log('flyerDescription: ' + flyerDescription);
    console.log('flyerID: ' + flyerID);  
    console.log('File path: ' + flyerUploadedPath); 

    if (directory){
      db.query('SELECT * FROM flyerinfo WHERE flyerURL = ?', [flyerUploadedPath], (err, results) => {
        if (err){
          return res.json({message: 'An error occured!' });
        } else if (results.length == 0) {
          db.query('INSERT INTO flyerinfo (flyerID, flyerName, flyerEventDate, flyerDescription, flyerURL) VALUES (?,?,?,?,?)', [flyerID, flyerName, flyerEventDate, flyerDescription, flyerUploadedPath], (err, res) => {
            if (err){
              return res.json({message: 'An Error Occured!' });
            }
          });
        }
      });
    };
    return res.status(200).send(req.files);
  }
});

module.exports = router;

Alternate code:

//----------------------------------------- BEGINNING OF PASSPORT MIDDLEWARE AND SETUP ---------------------------------------------------
const flyerDestination = './routes/Flyers'
const flyerStorage = multer.diskStorage({
  destination: function (req, file, cb){ 
    cb(null, flyerDestination)
  },
  filename: function (req, file, cb){
    if (fs.existsSync(path.join(flyerDestination,file.originalname))) {
      cb(new Error('Flyer already exists'));
    } else {
      cb(null, file.originalname);
    }
  }
});
const flyerUpload = multer({ storage: flyerStorage }).array('files');
//----------------------------------------- END OF PASSPORT MIDDLEWARE AND SETUP ---------------------------------------------------
router.post('/Flyer_Upload', flyerUpload, (req, res) => {
  const flyerName = req.body.flyerName;
  const flyerEventDate = req.body.flyerEventDate;
  const flyerDescription = req.body.flyerDescription;
  const flyerID = Math.floor(Math.random()*90000) + 10000;
  const flyerDirectory = 'http://localhost:3001/Flyers/'

  flyerUpload(req, res, function (err) {
    if (err instanceof multer.MulterError) {
        return res.status(500).json(err)
    } else if (err) {
        return res.status(500).json(err)
    }

    for (const file of req.files) {
      directory = path.dirname(file.path);
      const flyerUploadedPath = flyerDirectory + file.filename
      
      console.log('flyerName: ' + flyerName);
      console.log('flyerEventDate: ' + flyerEventDate);
      console.log('flyerDescription: ' + flyerDescription);
      console.log('flyerID: ' + flyerID);  
      console.log('File path: ' + flyerUploadedPath); 
  
      if (directory){
        db.query('SELECT * FROM flyerinfo WHERE flyerURL = ?', [flyerUploadedPath], (err, results) => {
          if (err){
            return res.json({message: 'An error occurred!' });
          } else if (results.length == 0) {
            db.query('INSERT INTO flyerinfo (flyerID, flyerName, flyerEventDate, flyerDescription, flyerURL) VALUES (?,?,?,?,?)', [flyerID, flyerName, flyerEventDate, flyerDescription, flyerUploadedPath], (err, res) => {
              if (err){
                return res.json({message: 'An Error Occurred!' });
              }
            });
          }
        });
      };
    }

    console.log('File path: ' + directory);
    return res.status(200).send(req.files);
  });
});
module.exports = router;

Solution

  • I managed to get the alternate version working by doing the following. Once I managed to get the configurations working, I could read all data.

    Middleware:

    const flyerDestination = './routes/Flyers'
    const flyerStorage = multer.diskStorage({
      destination: function (req, file, cb){ 
        return cb(null, flyerDestination)
      },
      filename: function (req, file, cb){
        if (fs.existsSync(path.join(flyerDestination,file.originalname))) {
          var err = new Error("Flyer already exists");
          err.statusCode = 409;
          return cb(err);
        } else {
          return cb(null, file.originalname);
        }
      }
    });
    const flyerUpload = multer({ storage: flyerStorage }).array('files');
    

    Route.post

    router.post('/Flyer_Upload', (req, res) => {
      flyerUpload(req, res, function (err) {
        const flyerName = req.body.flyerName;
        const flyerEventDate = req.body.flyerEventDate;
        const flyerDescription = req.body.flyerDescription;
        const flyerID = Math.floor(Math.random()*90000) + 10000;
        const flyerDirectory = 'http://localhost:3001/Flyers/';
        var uploadFlyer = true;
        var multerMessage = null;
        
        if (err instanceof multer.MulterError) {
          uploadFlyer = false;
          multerMessage = 'An Error Occurred During Upload!';
        } else if (res.status(409)) {
          uploadFlyer = false;
          multerMessage = 'Flyer already exists';
        } else if (res.status(500)){
          uploadFlyer = false;
          multerMessage = 'A Bad Request Was Recieved!';
        } else if (err){
          uploadFlyer = false;
          multerMessage = 'An Unknown Error Occurred!';
        } 
    
        if (!uploadFlyer){
          return res.json({message: multerMessage });
        }
        else {
          for (const file of req.files) {
            directory = path.dirname(file.path);
            const flyerUploadedPath = flyerDirectory + file.filename
    
            console.log('flyerName: ' + flyerName);
            console.log('flyerEventDate: ' + flyerEventDate);
            console.log('flyerDescription: ' + flyerDescription);
            console.log('flyerID: ' + flyerID);      
            console.log('File path: ' + flyerUploadedPath); 
            console.log('File path: ' + directory);
    
            if (directory){
              db.query('SELECT * FROM flyerinfo WHERE flyerURL = ?', [flyerUploadedPath], (err, results) => {
                if (err){
                  return res.json({message: 'An error occurred!' });
                } else if (results.length == 0) {
                  db.query('INSERT INTO flyerinfo (flyerID, flyerName, flyerEventDate, flyerDescription, flyerURL) VALUES (?,?,?,?,?)', [flyerID, flyerName, flyerEventDate, flyerDescription, flyerUploadedPath], (err, res) => {
                    if (err){
                      return res.json({message: 'An Error Occurred!' });
                    }
                  });
                }
              });
            };
          }
          return res.status(200).send(req.files);
        }
      });
    });
    module.exports = router;