Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Express(Node)-通过中间件周期发送错误消息的正确方法_Javascript_Node.js_Express_Error Handling - Fatal编程技术网

Javascript Express(Node)-通过中间件周期发送错误消息的正确方法

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

在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 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…)。如果我使用这个解决方案,我需要使它成为无状态的。例如,我可以用查询字符串来实现,但这对我来说也不是很方便。此外,它并不是直接回答问题,而是更直接地回答问题
也许有一种方法可以用express app轻松做到这一点,但我无法找到正确的方法。你能帮帮我吗

先谢谢你

编辑:有关可能答案的更多详细信息(第三种解决方案)


使用
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)