大家好,我使用 Express 做一 Web app,Express 与 Node 官方对于异步 Exception handling 似乎不太友善,抑或是我没厘清其撰写风格。
不晓得各为前辈能否指点迷津,有关于以下举例情况异步 Error exception。
var express = require('express');
var app = express();
app.get('/index', function (req, res) {
... // 代码,可能会有的错误
var isUndefined = undefined;
isUndefined.elements; // undefined.elements 系统要 throw error
});
app.get('/page1', function (req, res) {
... // 代码,可能会有的错误
throw "Error here";
});
以下我理想中的解法,但因为异步callback 这样是行不通的。
try {
app.get('/index', function (req, res) {
... // 代码,可能会有的错误
});
app.get('/page1', function (req, res) {
... // 代码,可能会有的错误
});
} catch (e) {
... // 处理 Error
}
使用bluebird这样的promise库
Product.findByIdAsync(productId).then(function(product){
//console.log("spread products= " + products);
return product.reject(function(err,result){
// console.dir(result);
Promise.resolve(result);
});
}).then(function(result){
if(result.ok == 1){
return Product.findByIdAsync(productId);
}
}).then(function(product){
//console.log("spread products= " + products);
expect(product.status).to.equal(2);
done()
}).catch(function(err) {
done(err);
});
这里面是对模型做的,在路由里对业务逻辑处理也可以
在JavaScript中try…catch是无法捕获异步代码抛出的异常的,node对于异步代码的标准错误处理方式是通过callback的第一个参数传递错误 而Express的设计是通过middleware来统一处理错误,可以看这里:http://expressjs.com/guide/error-handling.html
app.get('/index', function (req, res) {
try {
... // 代码,可能会有的错误
} catch (e) {
console.log(e)
}
});
可以在callback中用try catch,我更推荐这样的写法
app.get('/', listenr);
function listener(req, res) {
//try catch here
}
@ravenwang @i5ting 谢谢两位前辈,实不相瞒其实我现在就是使用 async callback 的回调机制来处理我「可预期得错误」,但是以下的举例程式码因为设计出现漏洞,如果没有 try catch 做最后一道防线,Node 在执行时就会直接 crash 了(专案目前已上线,希望就算有些小漏洞也不至于系统 crash,写入 log 之后再修正就行)。
我提到自己「可能不可预期的错误」(撰写上的粗心):
app.get('/index', function (req, res) {
async.waterfall([
function (callback) {
if (某种情况为 true 时) {
callback(null);
} else {
callback('Error'); // 这里作 callback error
}
},
function (callback) {
var objectA = { elementA: 123 };
callback(null, objectA);
}
], function (err, objectA) {
// 上述的 callback('Error'); 并无传递 objectA
// 所以亦即 undefined.elementA,这样子 Node 会 Crash!
console.log(objectA.elementA);
});
});
对于一些可能捕获不到的错误,可以用
process.on('uncaughtException', function(err) {
//log it
});
来保证node不退出,最好用log4js日志这些未捕获的错误。这是最后一道防线,因为错误是未知的,所以可能造成某个服务不可能用,所以需要谨慎使用
@dayuoba 懒羊羊前辈前述的方法我有想到,目前40 ~ 50 个 app router 看来这可能是唯一解了,前辈后面提到的建议写法获益良多,谢谢你连续几天的帮忙。不晓得对于此类 app 应用,前辈有没有些 design pattern 可供参考长进呢?