我在Express中编写了一系列REST API,并希望编写一种强大而一致的方法来处理错误并将其呈现给用户.到目前为止,我使用的中间件如下所示:
app.use(function(req, res, next){
res.render('404', { status: 404, error: 'not_found', error_description: 'the url '+req.url+' could not be found' });
});
app.use(function(err, req, res, next) {
switch (err.name) {
case 'CastError':
res.status(400);
return res.send({code:400, error: 'cast_error', error_description: err});
default:
console.log(err);
return res.send({code:500, error: 'internal_error', error_description: 'something went horribly wrong!'});
}
});
Run Code Online (Sandbox Code Playgroud)
现在问题在于错误可能来自应用程序的任何部分.例如,Mongoose会触发"CastError"之类的错误,可能会出现一般系统错误(无法连接到数据库),还会出现用户验证错误.
现在有些错误我想向用户显示一条消息(例如验证错误或告诉他们API请求有什么问题),而其他我想要隐藏用户的错误.
所以看一下验证错误:
throw new Error('not a valid project id');
Run Code Online (Sandbox Code Playgroud)
此刻,它只是作为一般500错误而被捕获,并且没有向用户显示有用的消息.如何将上述错误与一般系统错误区分开来,以便对它们进行不同的处理?是否有我可以使用的错误类型属性(可能是err.name).如果是这样,我该如何使用它?
概念创意(obv不起作用):
throw new Error('validation', 'not a valid project id');
Run Code Online (Sandbox Code Playgroud)
要么
throw new Error('not a valid project id').name('validation');
Run Code Online (Sandbox Code Playgroud)
Errors是对象,可以分配其他属性.您可以在构造错误后为错误添加更多属性.还要注意,操作数throw不必是一个Error,它可以是任何其他对象.
var validationError = new Error('Not a valid project ID');
validationError.type = 'validation';
throw validationError;
Run Code Online (Sandbox Code Playgroud)
更好的选择是使用继承自定义的错误类Error.
function ValidationError(message) {
if(!(this instanceof ValidationError)) {
return new ValidationError(message);
}
var err = this.err = Error.call(this, message);
this.message = message;
Object.defineProperty(this, 'stack', {
get: function () {
return err.stack;
}
});
}
ValidationError.prototype = Object.create(Error.prototype, {constructor: ValidationError});
Run Code Online (Sandbox Code Playgroud)
此方法允许您ValidationError使用instanceof运算符区分s与其他错误.这是koa应用程序的摘录:
app.use(function *() {
try {
if(this.method != 'GET') {
yield this.connection.beginTransaction();
yield *next;
yield this.connection.commit();
} else {
yield *next;
}
} catch(err) {
if(err instanceof ValidationError) {
this.body = err.message;
this.status = 422;
} else {
throw err; //let the framework notify the client of 500 Internal Server errors
}
if(this.method != 'GET') {
yield this.connection.rollback();
}
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2095 次 |
| 最近记录: |