我使用的是路由器的中间件来检查,如果该请求是否有效。另外,我使用的是全局错误处理程序中间件在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我的文件。
我怎样才能做到这一点?
不知道你的checkIfAccountIdExists
功能的行为,我的猜想是,它返回一个承诺,它始终与false|undefined|null
解决;是这样的:
checkIfAccountIdExists(id).then((exists) => console.log(exists));
// outputs "false" or "undefined" or "null"
这是我的猜想,因为否则你.get('/')
路线甚至不应该进入,考虑next()
是如何工作的。
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))
此外,承诺(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)也将处理错误。注:同步代码中的错误会以快递捕获。
更多信息: