美好的一天!我在这里看到了类似问题的答案(How is req and res accessible accross modules in Express.js),但这个答案的日期是2011年4月......这个问题的情况非常相似,但是,我怎么想,我从这一点开始,在那些答案中被提出 - 它没有用。在这些答案中使用了exports.something=
而不是module.exports
。在我读过的许多教程中,使用module.exports
更好,但忘了原因:)仅供参考 - 我使用快速4.x,节点4.5.x.因此,我会尝试简洁地解释我的问题,提供评论并描述行为:
我有一个简单的实验应用程序。
.
├── app.js
├── bin
├── config
├── createDb.js
├── error
├── libs
├── middleware
├── models
├── node_modules
├── ownroutes
├── package.json
├── public
├── routes
└── views
在error
目录中,我创建了一个带有customError的文件,该文件导出到routes
目录:
// CustomError file
var path = require('path');
var util = require('util');
var http = require('http');
function HttpError(status, message){
Error.apply(this, arguments);
Error.captureStackTrace(this, HttpError);
this.status = status;
this.message = message || http.STATUS_CODES[status] || "Error";
}
util.inherits(HttpError, Error);
HttpError.prototype.name = "HttpError";
module.exports = HttpError;
在middleware
目录中,我试图创建一个ErrorHandling中间件,但它不起作用。我的ErrorHandling函数也导出到routes
目录:
// ErrorHanling middleware file
function httpErrorHandler(err, req, res, next){
console.log("THIS IS REQUEST" +req+ "END OF REQUEST"); //just for checking
res.sendHttpError = function(err){
console.log("THIS IS RESPONSE" +res+ "END OF RESPONSE");//just for checking too
res.status(error.status);
if (res.req.headers['x-requested-with'] == 'XMLHttpRequest'){
res.json(err);
} else {
res.render("error", {error: error, message: "ALL RIGHT!!!!"});
}
};
next();
};
module.exports = httpErrorHandler;
最后,index.js
目录中的routes
:
//Router
//The problematical piece of code is here - see comments below
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var HttpError = require('../error/index'); // CustomError!!!!!!!!
var httpErrorHandler = require('../middleware/sendHttpError'); //ErrorHandling middleware!!!!!!
var util = require("util");
router.get('/', function(req, res, next){
res.render("templ");
});
router.get('/users', function(req, res, next){
User.find({}, function(err, users){
if(err) return next(err);
res.json(users);
})
})
//Now I pass the User with incorrectID for occuring of the CustomError
router.get('/users/:id', function(req, res, next){
User.findById(req.params.id, function(err, user){
if(err) return next(err);
if(!user){
next(new HttpError(404, "User Not Found"));
}
res.json(user);
})
});
//The problematical piece of code
router.use(function(err, req, res, next) {
if(typeof err == 'numder'){
err = new HttpError(err); // this is a CustomError
}
if (err instanceof HttpError){
console.log('TRUE'); // I have "TRUE" in the console
httpErrorHandler();
}
if(err == "CastError"){
console.log("CastError");
}else{
console.log('BLAAAAAAAAAAAAA');
}
next();
});
module.exports = router;
router
正常工作,但是当我尝试使用带有错误ID的用户时,我在控制台中有一条消息:TypeError: Cannot set property 'sendHttpError' of undefined
。所以,显然,"响应"是"未定义"和"请求"是"未定义"太。将此代码添加到ErrorHandling中间件文件中以定义req
和res
:
var express = require('express');
var req = express.request;
var res = express.response;
console.log(req); // the "req" object is visible here, but invisible in the function
没用。
当我将整个ErrorHandling函数直接设置到TRUE
中Router
的位置时,错误处理正确。
如果我在HttpErrorHandler()
中使用err, req, res, next
来呼叫Router
功能,我在控制台中有BLAAAA
并重定向到/
。为什么我的CustomError不会发生以及谁进行此重定向:中间件中的next()
或next()
中的Router
?
我完全理解必须定义req
和res
,但是如何在中间件ErrorHandling函数中定义它们?我是否可以将这种构建应用程序的方法视为正确的决策(模块化),或者可以更好地在路由器中直接设置ErrorHandling对象?