如何使用我的情况下,快递错误中间件?

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

我使用的是路由器的中间件来检查,如果该请求是否有效。另外,我使用的是全局错误处理程序中间件在server.js结束捕捉和处理所有的错误。

路由器里面,我面对实施这是一个问题。下面的代码将清楚地说明这个问题。

错误中间件errorHandler.js

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

我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
  });

该代码总是调用获取途径。至于这两个,我调用next()。如果我调用next()里面只有那么(),如果发生任何错误我的全局错误处理程序将得到跳过。

一种方法可以直接调用catch块中我errorHanler功能。但我想保持我的代码分离,真的不希望,要求每个路线中的ErrorHandler我的文件。

我怎样才能做到这一点?

javascript node.js express es6-promise
1个回答
1
投票

不知道你的checkIfAccountIdExists功能的行为,我的猜想是,它返回一个承诺,它始终与false|undefined|null解决;是这样的:

checkIfAccountIdExists(id).then((exists) => console.log(exists));
// outputs "false" or "undefined" or "null"

这是我的猜想,因为否则你.get('/')路线甚至不应该进入,考虑next()是如何工作的。

Understanding next():

调用next()(以快递的耻辱)一直扑朔迷离,而无需深入了解它。它基本上工作在3种方式:

  • next()(无参数) - >通执行在路由下回调
  • next('route')(字符串'route'参数) - >旁路途径的任何剩余的回调(移动到后面的任何路由)
  • next(err)(任何其他truthy参数,除了'route') - >调用错误处理程序。

在特定情况下,我的假设是,checkIfAccountIdExists()false|undefined|null解决,基本上是调用next(err)签名,但由于err不是truthy,它视为一个next()签名,移动到下一个路线回调。我会检查checkIfAccountIdExists()的理智这一点。

使用next()与承诺

当使用承诺,一定要记住,你的.then()(这意味着你的履行处理)的第一个参数总是会收到一个参数是很重要的!

promise.then(callback);

function callback() {
  console.log(arguments.length); // ALWAYS 1
}

出于这个原因,你应该总是避免设置next()作为履行处理程序的承诺。否则,一旦你checkIfAccountIdExists()true解决,它实际上将调用next(err)签名!

总是写:promise.then(() => next())而不是promise.then(next),以确保您拨打next没有参数。

promise.catch(next)然而罚款,因为它是一样的promise.catch((err) => next(err))

A bit more info on Promises

此外,承诺(thenables)允许在.then()两个参数,一个是实现处理器和一个拒绝处理。例如:promise.then(onFulfillment, onRejection)这类似于调用promise.then(onFulfillment).catch(onRejection)除的错误是如何抓住!

  • 对于.then(onFulfillment, onRejection)时引发的内部onFulfillment任何错误永远不会被抓到onRejection
  • 对于.then(onFulfillment).catch(onRejection)时引发的内部onFulfillment任何错误也被onRejection

在你的情况,这意味着你可以安全地写

checkIfAccountIdExists.then(() => next(), next);

因为接下来的路线(onFulfillment ARG)也将处理错误。注:同步代码中的错误会以快递捕获。

更多信息:

© www.soinside.com 2019 - 2024. All rights reserved.