我正在使用Restify,在Restify库的某个地方,由于用户端的一些错误输入,引发了一个异常。下面我有一些简化的代码来重现这个问题。下面例子中的问题出现在一个异步函数中,该函数试图执行不存在的函数。发生的情况是抛出一个异常,然后在"server.on('uncaughtException.."函数中捕获,但"err"对象实际上是"IncomingMessage"类型,而不是"Error"类型。我对此有一些问题。
1)抛出的异常是否应始终为"Error"类型,如果不是,则为这是Restify中的一个bug?
2) 对于接受回调参数的库来说,同时设置如果出现错误,则使用"err"参数,并让客户端在回调而不是库抛出异常?
var restify = require('restify');
//Test with long stack traces and without it.
//var longStackTraces = require('long-stack-traces');
const server = restify.createServer({
name: 'myapp',
version: '1.0.0'
});
server.get('/', function (req, res, next) {
try {
setTimeout(function () {
doesntexist.nofunction();
}, 200);
return next();
} catch (err) {
console.log("Caught error");
}
});
server.on('uncaughtException', function (err) {
console.log("uncaught exception1: " + err.constructor);
});
process.on('uncaughtException', function (err) {
console.log("uncaught exception2: " + err.constructor);
});
server.listen(9123, function () {
console.log('%s listening at %s', server.name, server.url);
});
测试:
curl http://localhost:9123
没有长堆栈跟踪的控制台输出:
myapp listening at http://[::]:9123
uncaught exception1: function IncomingMessage(socket) {
Stream.Readable.call(this)
...
Error: uncaught exception1
at Server.<anonymous> (/usr/apps/myapp/Temp.js:22:12)
at emitMany (events.js:132:20)
at Server.emit (events.js:201:7)
at Domain.onError (/usr/apps/myapp/node_modules/restify/lib/server.js:968:18)
at emitOne (events.js:96:13)
at Domain.emit (events.js:188:7)
at Domain._errorHandler (domain.js:97:23)
at process._fatalException (bootstrap_node.js:293:33)
没有长堆栈跟踪的控制台输出:
- 节点风格的回调函数应该有一个以
err
为第一个参数的签名。这本身没有任何规范,但却是一种社区规范
您的代码如下:
server.get('/', function (req, res, next) {
try {
setTimeout(function () {
doesntexist.nofunction();
}, 200);
return next();
} catch (err) {
console.log("Caught error");
}
});
我会这样重写:
server.get('/', function (req, res, next) {
setTimeout(function () {
try {
doesntexist.nofunction();
next();
} catch (err) {
next(err);
}
}, 200);
});
next
是一个节点样式的回调,err
作为第一个参数,这是传统的。通过在需要时提供err
参数来使用它。