Javascript 如何在我的案例中使用快速错误中间件?

Javascript 如何在我的案例中使用快速错误中间件?,javascript,node.js,express,es6-promise,Javascript,Node.js,Express,Es6 Promise,我正在使用路由器中间件来检查请求是否有效。此外,我还在server.js的末尾使用一个全局错误处理程序中间件来捕获和处理所有错误 在路由器内部,我在实现这一点时遇到了一个问题。以下代码将清楚地说明问题 错误中间件errorHandler.js module.exports = function(err, req, res, next) { //some logic return res.status(400 or 500).json({err}); }; My server.j

我正在使用路由器中间件来检查请求是否有效。此外,我还在server.js的末尾使用一个全局错误处理程序中间件来捕获和处理所有错误

在路由器内部,我在实现这一点时遇到了一个问题。以下代码将清楚地说明问题

错误中间件errorHandler.js

module.exports = function(err, req, res, next) {
    //some logic
    return res.status(400 or 500).json({err});
};
My server.js短版本

const express = require('express');
const app = express();

app.use('/account/:accid/users', userRouteHandler);

const errorHandler = require('PATH to errorHandler.js file');
app.use(errorHandler);

app.listen(3000, () => console.log(`Example app listening on port 3000!`));
userRouteHandler文件

var express = require('express');
var router = express.Router({ mergeParams: true });
router.use(express.json());

// middleware to use for all requests
router.use(function(req, res, next) {

  /**** PROBLEM / CONFUSION ****/

  checkIfAccountIdExists(req.params.accid) //if exists resolve(count) else reject(new Error)
    .then(next)   //I want to allow calling the get if it exists
    .catch(next); //for error it should call the global error handler
});

router
  .get('/', function(req,res,next){
    console.log("entering here"); 
    findAllTheUsers({accid:req.params.accid})
      .then(users=>res.status(200).json(users);
      .catch(err=>next(err)); //ensure it can call the global error handler
  });
代码总是调用get路由。至于这两个,我下一个打电话。如果我只在内部调用next,那么如果发生任何错误,我的全局错误处理程序将被跳过

一种方法是直接调用catch块中的errorHanler函数。但是我想把代码分开,不想在每个路由中都需要我的errorHandler文件


如何实现这一点?

在不知道checkifaccountedexists函数的行为的情况下,我的假设是它返回的承诺总是以false | undefined | null;大概是这样的:

checkIfAccountIdExists(id).then((exists) => console.log(exists));
// outputs "false" or "undefined" or "null"
这是我的假设,因为考虑到下一步的工作方式,否则您的.get'/'路径甚至不应该进入

理解下一步: 在没有深入了解的情况下,直呼“快递的耻辱”总是令人困惑。它基本上有三种工作方式:

下一个无参数->将执行传递给 路线 下一个'route'字符串'route'参数->绕过路由中的任何剩余回调将移动到随后的任何路由中 nexterr任何其他truthy参数,除了“route”->调用错误处理程序。 在您的具体案例中,我的假设是checkifaccountedexists使用false | undefined | null进行求解,本质上调用nexterr签名,但由于err不是truthy,因此它被视为下一个签名,移动到下一个路由回调。我要检查一下支票会计人员的健康状况

在承诺中使用next 在使用承诺时,重要的是要记住。的第一个参数,这意味着您的履行处理程序将始终收到一个参数

因此,您应该始终避免将next设置为承诺的实现处理程序。否则,一旦您的checkifaccountedexists将使用true进行求解,它将实际调用nexter签名

总是写:promise.then=>next而不是promise.thennext,以确保调用next时没有参数

不过,编写promise.catchnext很好,因为它与promise.catcherr=>nexter相同

更多关于承诺的信息 此外,PromissionsEnables允许上有两个参数。然后,一个是实现处理程序,另一个是拒绝处理程序。 示例:promise.thenonFulfillment,onRejection,类似于调用promise.thenonFulfillment.CathonRejection,除了如何捕获错误之外

对于.thenonFulfillment、onRejection,会抛出任何错误 内心的满足永远不会被拒绝抓住。 For.thenonFulfillment.catchonRejection抛出的任何错误 内部onFulfillment也会被onRejection捕获 对你来说,这意味着你可以安全地写作

checkIfAccountIdExists.then(() => next(), next);
因为下一个路由onFulfillment arg也将处理错误。 注意:express将捕获同步代码中的错误

更多信息:


checkIFaccountedExistsid函数返回一个承诺,如果id存在并拒绝错误实例,则该承诺得到resolvedcount。如果id不存在,它将传递一个自定义错误对象或Mongoose错误对象。所以我的下一个恐惧总是被召唤。我不知道的是next是重载的,任何truthy参数都直接调用错误处理程序。谢谢你的解释!:事实上,我解决了这个替代方法,你能告诉我这是好的还是坏的做法吗?app.use'/account/:accid/users',functionreq,res,next{return db.Org.isExists{accid:req.params.accid}。然后使用function{return userroutehandlereq,res,next;}.catchnext;};这对我的案子很有效。
checkIfAccountIdExists.then(() => next(), next);