环境:express+sequelize 代码的意图是统一处理router中的异常,想当然的写了段try/catch,
var m = ['get','post','put','delete'];
m.forEach(function(type){
var handlers = app.routes[type];
if(handlers){
handlers.forEach(function(handler){
//TODO:need to config the excluded handler path,not the hard code.
if(handler.path !== '/' && handler.path !== '/auth'){//the '/auth' is the login url.
handler.callbacks = [authIdentity].concat(handler.callbacks);
}
handler.callbacks.forEach(function(callback){
var packageCallBack = function(req,res,next){
try{callback(req,res,next);}
catch(e){
debugger;
//TODO:need to implement other logics.
if(e instanceof AppError){
res.send(e);
}
next(e);
}
};
callback = packageCallBack;
});
});
}
});
在处理请求的方法中,想当然的抛异常.
exports.authenticate= function(req, res, next){
var daos = app.get('models')
,user = daos.user
,_vaule = {};
user.find({where:{login:req.param('login')}}).success(
function(value){
if(value){
var result = md5.validate(value.hashed_password,req.param('passwd'));
if(result){
req.session.userinfo = value.login;
var url = req.param('url');
if(url){
res.redirect(url);
}
}else{
throw new AppError('invalid user or passwd.');
//next(new AppError('invalid user or passwd.'));
}
}
else{
throw new AppError('the user does not exist.');
//next(new AppError('the user does not exist.'));
}
});
};
期望就是抛出的异常,有外围的try/catch去捕获,相信很多初学者都会犯类似的错误,在异步回调的时空里,回调方法抛出异常,往往就是噩梦,因为回调方法里的异常,try有啥用?
个人有个不恰当的比喻: node就像是一根绳子,异步回调是无处不在的绳子节点,抛异常好比剪刀,一刀下去,绳子断了. 最终的处理方式,已经很明显了,使用express中的next去传递异常,而不是抛~ 这里强调一下,回调和异步回调不是同一个概念,这里有篇文章讲解了回调捕获异常和异步回调捕获异常的区别 http://www.html-js.com/archives/category/nodejs/page/2
下面几个链接讲述了node中异常处理的基本方式: http://snmaynard.com/2012/12/21/node-error-handling/ http://stackoverflow.com/questions/7151487/error-handling-principles-for-nodejs-express-apps http://stackoverflow.com/questions/7310521/node-js-best-practice-exception-handling