使用 multer 和expressjs上传文件时的错误处理

问题描述 投票:0回答:10

我正在使用multer将文件保存在通过express和nodejs开发的服务器上。

我正在使用以下代码。

var express = require('express'),
    multer  = require('multer')

var app = express()

app.get('/', function(req, res){
  res.send('hello world');
});

app.post('/upload',[ multer({ dest: './uploads/'}), function(req, res){

    res.status(204).end()
}]);

app.listen(3000);

Multer 为我将文件保存在指定的目标文件夹中。

所有这些都工作正常,但我有以下问题:

  1. 如果由于各种原因文件保存失败,看起来我的路线将始终返回状态204。
  2. 我不确定状态 204 是否在文件保存后返回,或者在文件异步保存时返回状态 204。
node.js express multer busboy
10个回答
25
投票

这是编写处理上传和错误的 multer 中间件的方法

const multer = require("multer");

function uploadFile(req, res, next) {
    const upload = multer().single('yourFileNameHere');

    upload(req, res, function (err) {
        if (err instanceof multer.MulterError) {
            // A Multer error occurred when uploading.
        } else if (err) {
            // An unknown error occurred when uploading.
        }
        // Everything went fine. 
        next()
    })
}

15
投票

您可以使用

onError
选项处理错误:

app.post('/upload',[
  multer({
    dest    : './uploads/',
    onError : function(err, next) {
      console.log('error', err);
      next(err);
    }
  }),
  function(req, res) {
    res.status(204).end();
  }
]);

如果您调用

next(err)
,您的路由处理程序(生成 204)将被跳过,错误将由 Express 处理。

认为(不是100%确定,因为这取决于

multer
如何实现)保存文件时将调用您的路由处理程序。您可以使用
onFileUploadComplete
在上传完成时记录一条消息,并将其与调用路由处理程序时进行比较。

查看代码,

multer
当文件完全上传后调用下一个中间件/路由处理程序。


8
投票

试试这个

var upload = multer().single('avatar')

app.post('/profile', function (req, res) {
  upload(req, res, function (err) {
    if (err) {
      // An error occurred when uploading 
      return
    }

    // Everything went fine 
  })
}

参考:

http://wiki.workassis.com/nodejs-express-get-post-multipart-request-handling-example/

https://www.npmjs.com/package/multer#error-handling


1
投票

从下面的代码中可以看到(来自 muter index.js 文件的源代码),如果不传递 onError 回调,错误将由 express 处理。

    fileStream.on('error', function(error) {
      // trigger "file error" event
      if (options.onError) { options.onError(error, next); }
      else next(error);
    });

1
投票

当用户向您发送任何内容时请小心系统

我通常会设置更多[*option1]:

process.on('uncaughtException', function(ls){
  // console.log(ls);
  (function(){})();
});

然后:

var upload= multer({ dest: __dirname + '/../uploads/' }).single('photos');
// middle ..
upload(req, res, function (err) {
  if (err instanceof multer.MulterError) {
    // A Multer error occurred when uploading.
    console.log('MulterError', err);
  } else if (err) {
    // An unknown error occurred when uploading.
    // Work best when have [*option1]
    console.log('UnhandledError', err);
  }
  if(err) {
    return res.sendStatus(403);
  }
  res.sendStatus(200);
});

包:“multer”:“^1.4.2”


1
投票
    var multer = require('multer')
    var upload = multer().single('avatar')
     
    app.post('/profile', function (req, res) {
      upload(req, res, function (err) {
        if (err instanceof multer.MulterError) {
          handle error
        } else if (err) {
          handle error
        }
        else{
          write you code
        }
      })
    })

您可以从文档

中看到这一点

1
投票

根据multer文档(https://github.com/expressjs/multer#error-handling

错误处理

遇到错误时,Multer 会将错误委托给 Express。您可以使用标准的 Express 方式显示一个漂亮的错误页面。

如果您想专门从 Multer 捕获错误,您可以自己调用中间件函数。此外,如果您只想捕获 Multer 错误,您可以使用附加到 multer 对象本身的 MulterError 类(例如 err instanceof multer.MulterError)。

代码示例

   const multer = require('multer')
   const upload = multer().single('avatar')
   
   app.post('/profile', function (req, res) {
     upload(req, res, function (err) {
       if (err instanceof multer.MulterError) {
         // A Multer error occurred when uploading.
       } else if (err) {
         // An unknown error occurred when uploading.
       }
   
       // Everything went fine.
     })
   })

当我们用最新版本的 multer (v1.4.5-lts.1) 重写本题中的代码时

const express = require('express');

const multer = require('multer');

const app = express();

const upload = multer({ dest: './uploads/' }).single('fieldName');

app.get('/', (req, res) => {
    res.send('hello world');
});

app.post(
    '/upload',
    (req, res, next) => {
        upload(req, res, (err) => {
            if (err instanceof multer.MulterError) {
                res.status(404).send(err + 'Upload failed due to multer error');
            } else if (err) {
                res.status(404).send(err + 'Upload failed due to unknown error');
            }
            // Everything went fine.
            next();
        });
    },
    (req, res) => {
        res.status(204).end();
    }
);

app.listen(3000);

要检查 Multer 错误和非 multer 错误,我们可以使用 fileFilter 和限制添加验证 例如: 我正在添加 CSV 文件过滤方法和一些限制

// CSV file filter - will only accept files with .csv extension
const csvFilter = (req, file, cb) => {
    console.log('csv filter working');
    if (file.mimetype.includes('csv')) {
        cb(null, true);
    } else {
        cb('Please upload only csv file.', false);
    }
};

// adding the csv file checking, file number limit to 1 and file size limit 10 1kb
const upload = multer({
    dest: './uploads/',
    fileFilter: csvFilter,
    limits: { files: 1, fileSize: 1024 } 
}).single('fieldName');

当我们尝试上传非 CSV 文件或 >1kb 大小的文件或多个文件时,我们可以看到抛出不同的错误。


0
投票

我知道已经晚了,但可能对其他人有帮助。

这是我处理错误并在我的express/typescript中安全使用它的方法 项目。

const upload = (fieldName: string) => {
  return (req: Request, res: Response, next: NextFunction) => {
    return multer({
      storage: multer.diskStorage({
        destination: (req, file, cb) => {
          if (file.fieldname === 'post') {
            return cb(null, `${path.join(path.dirname(__dirname), 'uploads/postImg')}`);
          } else if (file.fieldname === 'profile') {
            return cb(null, `${path.join(path.dirname(__dirname), 'uploads/ProfilePic')}`);
          } else {
            return cb(new Error(`${file.fieldname} is incorrect`), null);
          }
        },
        filename: (req, file, cb) => {
          return cb(null, `${file.originalname}-${Date.now()}-${file.fieldname}`);
        },
      }),
      fileFilter: (req, file, cb) => {
        const fileExtension = file.mimetype.split('/')[1];
        if (!(fileExtension in allowedFiles)) return cb(null, false);
        return cb(null, true);
      },
      dest: `${path.join(path.dirname(__dirname), 'uploads')}`,
      limits: {
        fileSize: 1024 * 1024 * 3, // 3MB
        files: 1,
      },
    }).single(fieldName)(req, res, (err: any) => {
      if (err instanceof multer.MulterError) {
        // handle file size error
        if (err.code === 'LIMIT_FILE_SIZE') return res.status(400).send({ error: err.message });
        // handle unexpected file error
        if (err.code === 'LIMIT_UNEXPECTED_FILE') return res.status(400).send({ error: err.message });
        // handle unexpected field key error
        if (err.code === 'LIMIT_FIELD_KEY') return res.status(400).send({ error: err.message });
      }
      next();
    });
  };
};




app.post("/upload", (req: Request, res:Response)=>{
res.json({message:"file uploaded"})
})

0
投票

我认为最好的方法是使用中间件处理错误。

const multerErrorHandling = (err, req, res, next) => {
if (err instanceof multer.MulterError) {
  res.status(400).send("Multer error: " + err.message);
} else {
  next();
}
};
  // you should use after multer to send another respond.
  app.post("/upload", singleUpload,multerErrorHandling,(req, res) => {

0
投票

由于 Multer 是专为 Express 用作中间件而设计的,因此默认调用

next(err)
,它属于最近的错误处理程序中间件

var express = require('express'),
  multer = require('multer')

var app = express()

app.get('/', function (req, res) {
  res.send('hello world');
});

app.post('/upload', multer({ dest: './uploads/' }),

  function (req, res, next) {
    // your logic goes here

    res.status(204).end()
  },
  function (err, req, res, next) {
    // handle your error here
    // if (err instanceof multer.MulterError) {
    //   // handle file size error
    //   if (err.code === 'LIMIT_FILE_SIZE') return res.status(400).send({ error: err.message });
    //   // handle unexpected file error
    //   if (err.code === 'LIMIT_UNEXPECTED_FILE') return res.status(400).send({ error: err.message });
    //   // handle unexpected field key error
    //   if (err.code === 'LIMIT_FIELD_KEY') return res.status(400).send({ error: err.message });
    // }

    res.status(400).end()
  },);

app.listen(3000);
© www.soinside.com 2019 - 2024. All rights reserved.