Javascript Express(Node)-通过中间件周期发送错误消息的正确方法
在express应用程序中,向视图发送错误消息的正确方式是什么 (我们假设代码是同步的) 例1:Javascript Express(Node)-通过中间件周期发送错误消息的正确方法,javascript,node.js,express,error-handling,Javascript,Node.js,Express,Error Handling,在express应用程序中,向视图发送错误消息的正确方式是什么 (我们假设代码是同步的) 例1: // Route Router.route('/') .get(controller.getIndex); // Controller Controller.getIndex = function (req, res, next) { doSomething(function (err, datas) { if (err) { res.locals.err = 'error mes
// Route
Router.route('/')
.get(controller.getIndex);
// Controller
Controller.getIndex = function (req, res, next) {
doSomething(function (err, datas) {
if (err) { res.locals.err = 'error message'; }
// ...
});
res.render(/* view */);
};
// View
<p class="error">${ out.global.err }</p>
//路由
Router.route(“/”)
.get(controller.getIndex);
//控制器
Controller.getIndex=函数(请求、恢复、下一步){
剂量测量(功能(错误、数据){
if(err){res.locals.err='错误消息';}
// ...
});
res.render(/*视图*/);
};
//看法
${out.global.err}
这里没有问题:如果有错误,我将在响应中存储一条消息,并在视图中显示它
例2:
// Route (with multiple middlewares)
Router.route('/')
.get(firstMiddleware, otherMiddleware/*, otherMiddleware2, etc */, controller.getIndex);
// firstMiddleware (always need to be called)
firstMiddleware = function (req, res, next) {
doAlsoSomething(function (err, datas) {
if (err) { res.locals.err = 'error message'; }
// ...
});
next();
};
// otherMiddleware, otherMiddleware2 (need to be called only if no errors)
otherMiddleware = function (req, res, next) {
next();
};
// Controller (need to be called only if want to display the view)
Controller.getIndex = function (req, res, next) {
doSomething(function (err, datas) {
if (err) { res.locals.err = 'error message'; }
// ...
});
res.render(/* view */);
};
// View
<p class="error">${ out.global.err }</p>
//路由(具有多个中间件)
Router.route(“/”)
.get(firstMiddleware、otherMiddleware/*、otherMiddleware2等*/、controller.getIndex);
//firstMiddleware(始终需要调用)
firstMiddleware=函数(req、res、next){
doAlsoSomething(函数(错误、数据){
if(err){res.locals.err='错误消息';}
// ...
});
next();
};
//otherMiddleware、otherMiddleware2(只有在没有错误时才需要调用)
otherMiddleware=函数(req、res、next){
next();
};
//控制器(仅当要显示视图时才需要调用)
Controller.getIndex=函数(请求、恢复、下一步){
剂量测量(功能(错误、数据){
if(err){res.locals.err='错误消息';}
// ...
});
res.render(/*视图*/);
};
//看法
${out.global.err}
在本例中,将始终调用otherMiddleware。这不是我想要的,它应该停止中间件的循环,以防出现错误。然后,如果需要在视图上显示错误,则应调用带有错误消息的Controller.getIndex()
,如示例1所示。如果错误有自己的视图(如404500…),则不应调用控制器.getIndex()
,而应调用适当的视图。在任何情况下,如果otherMiddlewareX中发生错误,则不应调用“after”中间件(otherMiddlewareX+1,otherMiddlewareX+2…otherMiddlewareN)
有人能帮我找到一个“正确”的方法吗
编辑:
可能的答案(如有必要,我可以给出实施示例):
- 在每个中间件中设置一个条件
,以便在出现错误时通过调用if(res.locals.err)
next()跳转到下一个中间件代码>。那不太方便
- 使用
next('error message')调用错误处理中间件代码>但很难在一个函数中管理每个重定向(这是我使用的解决方案)
- 使用
next('route')每次使用路由复制来管理错误的代码>(类似于错误处理中间件解决方案)
- 使用
res.redirect()代码>和闪存消息(会话、查询字符串、数据库、cookie…)。如果我使用这个解决方案,我需要使它成为无状态的。例如,我可以用查询字符串来实现,但这对我来说也不是很方便。此外,它并不是直接回答问题,而是更直接地回答问题
使用
next('error message')代码>我有一个错误处理程序中间件,需要在其中显示良好的视图。视图可以是500404406。。。还有一个200,上面有一条错误信息。首先,我需要给这个中间件提供状态代码,然后如果是200,我需要调用与错误对应的视图。问题是我并不总是知道调用哪个视图。我可以在/auth上发布帖子,需要重定向才能获取/login。我需要“硬编码”它,不能为每种情况编写相同的代码,或者我需要在每个next('error message')中传递视图/控制器代码>呼叫。甚至重定向也很难,因为有时我需要调用控制器,但有时我需要通过调用路由而不是控制器来完成另一个中间件周期,我找到的唯一方法是return app.\u router.handle(req,res,next)代码>这看起来更像是一个“黑客”,而不是一个正式的解决方案。如果我使用res.redirect()重定向;我回到第二个可能的答案,我需要传递一些即时消息。最后,这是我使用的解决方案(next(err)
),但我希望有更好的方法。如果您只使用一次otherMiddleware
,请删除它,然后将其内容移动到上一个中间件的else
块:
var checkForm=函数(请求、恢复、下一步){
validationResult(函数(错误、数据){
if(err){res.locals.err='错误消息';}
否则{
//只有在表格有效的情况下才做这些事情
//其他中间件代码
}
// ...
});
next();
};代码>我不确定我是否理解了您的整个问题,但我会使用和错误处理中间件,如下所示:
//第一个中间件
var firstMiddleware=函数(req、res、next){
doAlsoSomething(函数(错误、数据){
if(err){next('error message');}
// ...
next();//如果err为true,则调用renderView
});
};
//其他中间件
var otherMiddleware=函数(req、res、next){
//只有在没有错误的情况下才去做
next();
};
//控制器
Controller.getIndex=函数(请求、恢复、下一步){
剂量测量(功能(错误、数据){
if(err){next('error message');}
// ...
next();//如果err为true,则调用renderView
});
};
//此中间件在next之后运行(“错误消息”)
var handleError=函数(err、req、res、next){
res.locals.err=err.message;
}
//该中间件始终运行
var renderView=函数(请求、恢复、下一步){
res.render(/*视图*/);
}
//路线
Router.route(“/”)
.get(firstMiddleware、otherMiddleware/*、otherMiddleware2等*/、controller.getIndex、handleError、renderView)嘿,谢谢你