Chr*_*ill 8 javascript error-handling prototype node.js bluebird
我正在尝试为自定义错误实现一个模块.
应该可以使用此模块在app的require-statement中实例化单个错误:
var MyCustomError = require('custom-error')('MyCustomError');
Run Code Online (Sandbox Code Playgroud)
这是模块:
'use strict';
var _CACHE = {};
function initError(name) {
function CustomError(message) {
this.name = name;
this.message = message;
}
CustomError.prototype = Object.create(Error.prototype);
CustomError.prototype.constructor = CustomError;
_CACHE[name] = CustomError;
}
function createCustomError(name) {
if (!_CACHE[name]) {
initError(name);
}
return _CACHE[name];
}
module.exports = createCustomError;
Run Code Online (Sandbox Code Playgroud)
到目前为止,上面的要求一线工作正在进行中.
现在,在我的服务中,我想明确地捕获这个错误:
var MyCustomError = require('custom-error')('MyCustomError')
// ...
return fooService.bar()
.catch(MyCustomError, function (error) {
logger.warn(error);
throw error;
})
Run Code Online (Sandbox Code Playgroud)
如果我在测试中通过抛出MyCustomError来拒绝fooService.bar的承诺,那么这很有用.
但是,这只能起作用,因为我的测试和服务使用了相同的MyCustomError 实例.
例如,如果我删除了我的自定义错误模块中的缓存机制,则不会再达到/执行catch,因为bluebird不理解这两个错误的类型相同:
function createCustomError(name) {
//if (!_CACHE[name]) {
initError(name);
//}
return _CACHE[name];
}
Run Code Online (Sandbox Code Playgroud)
bluebird处理的具体代码位于catch_filter.js中,您可以在这里查看.
虽然这种方法在我的应用程序中运行,但是一旦多个模块使用自定义错误模块并且不再提供相同实例的共享,这将很快导致问题.
如何通过不比较实例,但错误类型本身来启动和运行此概念?
干杯,
克里斯托弗
我最终想出了一个稍微不同的方法。对于志同道合的人来说,结果是这样的:
错误工厂
var
vsprintf = require("sprintf-js").vsprintf;
function CustomErrorFactory(code, name, httpCode, message) {
// Bluebird catcher
this.predicate = function (it) {
return it.code === code;
};
this.new = function (messageParameters, details) {
return new CustomError(messageParameters, details);
};
this.throw = function (messageParameters, details) {
throw new CustomError(messageParameters, details);
};
function CustomError(messageParameters, details) {
this.code = code;
this.name = name;
this.message = vsprintf(message, messageParameters);
this.httpCode = httpCode;
this.details = details || {};
// Important: Do not swallow the stacktrace that lead to here.
// @See http://stackoverflow.com/questions/8802845/inheriting-from-the-error-object-where-is-the-message-property
Error.captureStackTrace(this, CustomError);
}
// CustomError must be instance of the Error-Object
CustomError.prototype = Object.create(Error.prototype);
CustomError.prototype.constructor = CustomError;
}
module.exports = CustomErrorFactory;
Run Code Online (Sandbox Code Playgroud)
错误
var
ErrorFactory = require("./ErrorFactory");
function initErrors() {
return {
Parameter: {
Missing: new ErrorFactory('1x100', 'ParameterMissing', 400, 'Parameter "%s" missing'),
Invalid: new ErrorFactory('1x200', 'ParameterInvalid', 400, 'Parameter "%s" invalid')
//..
},
Access: {
NotAccessible: new ErrorFactory('3x100', 'AccessNotAccessible', 403, 'Resource "%s" is not accessible for "%s"'),
//..
},
// ...
Request: {
//..
}
};
}
module.exports = initErrors();
Run Code Online (Sandbox Code Playgroud)
我创建了一个包含这些类的单独模块。
然后,在我的实现中,我可以单独捕获这样的错误:
function foo(request, reply) {
return bluebird
.resolve(bar)
.then(reply)
.catch(Errors.Parameter.Missing.predicate, function () {
return reply(boom.badRequest());
})
.catch(Errors.Entity.NotFound.predicate, function () {
return reply({}).code(204);
})
.catch(Errors.Entity.IllegalState.predicate, function (error) {
return reply(boom.badImplementation(error.message));
})
// any other error
.catch(function (error) {
return reply(boom.badImplementation(error.message));
});
}
Run Code Online (Sandbox Code Playgroud)
投掷
Errors.Entity.IllegalState.throw(['foo', 'bar']);
// or
throw Errors.Entity.IllegalState.new(['foo', 'bar']);
Run Code Online (Sandbox Code Playgroud)
要求
Errors = require('errors'); // all
EntityErors = require('errors').Entity; // one group
EntityNotFoundError = require('errors').Entity.NotFound; // one particular
Run Code Online (Sandbox Code Playgroud)
我仍然不明白为什么需要使用谓词函数而不是仅仅将错误对象传递给 catch 子句。但我可以接受。
| 归档时间: |
|
| 查看次数: |
718 次 |
| 最近记录: |