【问题标题】:Express error middleware not reached by asynchronous error异步错误未到达 Express 错误中间件
【发布时间】:2020-11-25 18:54:53
【问题描述】:

我正在尝试以简化的方式处理后端中的所有错误。在我的一个端点中,我将一些文档保存到我的 mongoose 数据库中,如果有任何错误,我会捕获它们并将它们通过调用 next(err) 传播到我的错误处理程序。这适用于 Promise 之外的错误,但不适用于在 catch() 子句中调用 next() 时。我的端点是这样定义的:

router.post("/", (req, res, next) => {
    let listToAdd = req.body;

    if (!(listToAdd instanceof Array)) {
        listToAdd = [listToAdd];
    }

    let persons = listToAdd.map(p => {
        return new Person(p)
    });

    Promise.all(persons.map(p => p.save()))
        .then(saved => {
            res.status(201).send(`Successfully saved document(s) with id(s): ${persons.map(p => p._id.toString())}`)
        })
        .catch(err => {
            next(err);  // This error never reaches my middleware
        });
    next();  // errors here be handled by middleware
});

我的 app.js,我的中间件注册的地方:

const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);

// Routes
const personalFileRouter = require("./endpoints/person");
const userRouter = require("./endpoints/user");

// Custom Middleware
const {myRequestLoggingMiddleware} = require("./middleware/express_logging");
const {myErrorLoggingMiddleware} = require("./middleware/express_logging");

// Create a new express app
const app = express();

// Use CORS to allow communication to frontend
app.use(cors());

// use bodyparser to parse url body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}));

// Use Express Sessions to track user logins
app.use(session({
  secret: process.env.PRIVATE_KEY,
  resave: true,
  saveUninitialized: false,
  store: new MongoStore({
    mongooseConnection: mongoose.connection
  })
}));

// Whenever we get a request on the form "/whatever" it should use the routes file to redirect
app.use("/person/", personalFileRouter);
app.use("/user/", userRouter);

app.use(myErrorLoggingMiddleware);  // <-- Register my middleware last

module.exports = app;

最后,我的中间件错误处理程序

function myErrorLoggingMiddleware(err, req, res, next) {  // Never reached :(
    if (res.headersSent) {
        return next(err)
    }

    if (err instanceof mongoose.Error.ValidationError) {
        validationErrorHandler(err, req, res);
    } else {
        defaultErrorHandler(err, req, res);
    }
    next();
}

exports.myErrorLoggingMiddleware = myErrorLoggingMiddleware;

【问题讨论】:

    标签: node.js mongodb express asynchronous error-handling


    【解决方案1】:

    嗯,这很尴尬。我不是 100% 确定为什么,但我认为当我在我的承诺之下调用 next() 时,它在承诺解决之前执行,函数已经运行,接下来是“用完”。因此,当 promise 稍后解析时,next() 是一个不引用任何中间件的空函数。然后我的解决方案是简单地删除最后一个 next()only 在我的承诺中调用 next 。

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2016-04-30
      • 2019-11-26
      • 2018-12-25
      • 1970-01-01
      • 2014-02-02
      • 2018-02-25
      相关资源
      最近更新 更多