我有一条接受文件上传的途径:

在app.js中

.
.
.
var upload = require('./routes/upload');
.
.
.
app.use('/upload', upload);
.
.
.

/* Need to start the application with NODE_ENV=production */
app.use(function (err, req, res, next){
    if (res.headersSent) {
        return next(err)
    }
    res.status(500)
    res.render('An error occured while trying to serve your request. Please send us an email if the error recurs.')
});
app.listen(3000);

在route/upload.js中,我在接受文件并在数据库中进行输入之前检查文件类型。我还在文件写入期间检查错误,尝试通过在handleFileUpload中调用next(err)传递给app.js中的错误处理程序,如下所示:
var express = require('express');
var router = express.Router();
var path = require('path');
var mysql = require('mysql');
var multer = require('multer');
var fs = require('fs');
var db = require('../database');

var MAGIC_NUMBERS = {
    jpg:  'ffd8ffe0',
    jpg1: 'ffd8ffe1',
    png:  '89504e47'
}

/* Adapted from https://evdokimovm.github.io/javascript/nodejs/expressjs/multer/2016/11/03/Upload-files-to-server-using-NodeJS-and-Multer-package-filter-upload-files-by-extension.html */
function checkMagicNumbers(magic) {
    if (magic == MAGIC_NUMBERS.jpg || magic == MAGIC_NUMBERS.jpg1 || magic == MAGIC_NUMBERS.png)
         return true;
}

function handleFileUpload(req, res, next){
    var upload = multer({
        storage: multer.memoryStorage(),
    }).single('fileUpload');

    upload(req, res, function(err) {
        var buffer   = req.file.buffer;
        var magic    = buffer.toString('hex', 0, 4);
        var filename = req.file.fieldname + '-' + req.file.originalname.replace(/\s+/g,'') + '-' + Date.now() + path.extname(req.file.originalname);

        if (checkMagicNumbers(magic)) {
            fs.writeFile('/uploads/' + filename, buffer, 'binary', function(err) {
                if (err){
                    console.log(err);
                    return next(err);
                }
                else{
                    req.savedfilename = filename;
                    next();
                }
            })
        } else {
            res.end('File is not of the following accepted types: jpeg, jpg, png.');
        }
    });
}

function handleDatabaseInsert(req, res, next)
{
    db.insertRecord(req.body.name, req.body.email, req.body.message,
         req.body.country, req.savedfilename, function(err, results){
            if(err)
                next(err);
    });
    res.end("Thank you for your participation! Please look forward to our email with updates.");
}

/* POST to Upload */
router.post('/', handleFileUpload, handleDatabaseInsert)

module.exports = router;

问题是当我试图捕获尝试写入文件并将其从handleFileUpload内部传递到app.js中的错误处理程序时可能发生的错误时,将调用下一个中间件handleDatabaseInsert而不是我制作的错误处理程序在使应用程序监听之前,请在app.js末尾使用该应用程序。

这是预期的行为吗?我以为会调用带有4个形式参数的函数来处理错误?

注意:我通过使用不存在的文件路径(在本例中为/uploads/而不是./uploads/)来有意模拟写入错误。

谢谢!

最佳答案

如果我理解正确,那么如果出现某种错误,您想停止该请求。为此,您只需停止调用next()
调用next()会运行创建的下一个中间件功能如果您不希望它运行下一个中间件项,请不要调用next()

您可能想用res.send(500)之类的方法代替next()或类似的方法。

如果要创建错误处理程序,也可以这样做:

http://expressjs.com/en/guide/using-middleware.html#middleware.error-handling

10-04 16:45