Javascript 如何在我的案例中使用快速错误中间件?
我正在使用路由器中间件来检查请求是否有效。此外,我还在server.js的末尾使用一个全局错误处理程序中间件来捕获和处理所有错误 在路由器内部,我在实现这一点时遇到了一个问题。以下代码将清楚地说明问题 错误中间件errorHandler.jsJavascript 如何在我的案例中使用快速错误中间件?,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
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);