trace-error
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -9,4 +9,12 @@ 'use strict'; | ||
var _weakmap = require('weakmap'); | ||
var _weakmap2 = _interopRequireDefault(_weakmap); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var privates = new _weakmap2.default(); | ||
var Exception = function () { | ||
@@ -16,8 +24,20 @@ _createClass(Exception, [{ | ||
value: function get(key) { | ||
return this.___base_exception___[key]; | ||
return this._getProperty('error', {})[key]; | ||
} | ||
}, { | ||
key: '_defineProperty', | ||
value: function _defineProperty(key, value) { | ||
var pr = privates.has(this) ? privates.get(this) : {}; | ||
pr[key] = value; | ||
privates.set(this, pr); | ||
} | ||
}, { | ||
key: '_getProperty', | ||
value: function _getProperty(key, def) { | ||
return privates.has(this) ? privates.get(this)[key] : def; | ||
} | ||
}, { | ||
key: 'stack', | ||
get: function get() { | ||
return this.___base_exception___.stack; | ||
return this._getProperty('error', {}).stack; | ||
} | ||
@@ -27,3 +47,3 @@ }, { | ||
get: function get() { | ||
return this.___base_exception___.name; | ||
return this._getProperty('error', {}).name; | ||
} | ||
@@ -33,3 +53,3 @@ }, { | ||
get: function get() { | ||
return this.___base_exception___.message; | ||
return this._getProperty('error', {}).message; | ||
} | ||
@@ -46,3 +66,3 @@ }]); | ||
var error = new (Function.prototype.bind.apply(Error, [null].concat(args)))(); | ||
Object.defineProperty(this, '___base_exception___', { configurable: false, value: error }); | ||
this._defineProperty('error', error); | ||
} | ||
@@ -49,0 +69,0 @@ |
@@ -15,2 +15,6 @@ 'use strict'; | ||
var _weakmap = require('weakmap'); | ||
var _weakmap2 = _interopRequireDefault(_weakmap); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -24,2 +28,4 @@ | ||
var privates = new _weakmap2.default(); | ||
var TraceError = function (_Exception) { | ||
@@ -54,3 +60,3 @@ _inherits(TraceError, _Exception); | ||
try { | ||
for (var _iterator = this.causes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
for (var _iterator = this.causes()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var cause = _step.value; | ||
@@ -85,30 +91,4 @@ | ||
}, { | ||
key: 'cause', | ||
value: function cause() { | ||
var index = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; | ||
return this.___trace_error_causes__[index]; | ||
} | ||
}, { | ||
key: 'causes', | ||
value: function causes() { | ||
return this.___trace_error_causes__; | ||
} | ||
}, { | ||
key: 'stack', | ||
get: function get() { | ||
if (this.___trace_error_use_base___) { | ||
return _get(Object.getPrototypeOf(TraceError.prototype), 'stack', this); | ||
} | ||
Object.defineProperty(this, '___trace_error_use_base___', { value: true, configurable: true }); | ||
var stack = this.getLongStack(); | ||
Object.defineProperty(this, '___trace_error_use_base___', { value: false, configurable: true }); | ||
return stack; | ||
} | ||
}, { | ||
key: 'messages', | ||
get: function get() { | ||
value: function messages() { | ||
var messages = [_get(Object.getPrototypeOf(TraceError.prototype), 'message', this)]; | ||
@@ -121,12 +101,9 @@ | ||
try { | ||
for (var _iterator2 = this.causes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
for (var _iterator2 = this.causes()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var cause = _step2.value; | ||
if (cause instanceof Error) { | ||
var message = cause.messages || cause.message; | ||
if (Array.isArray(message)) { | ||
messages = messages.concat(message); | ||
} else { | ||
messages.push(message); | ||
} | ||
if (cause instanceof TraceError) { | ||
messages = messages.concat(cause.messages()); | ||
} else if (cause instanceof Error) { | ||
messages.push(cause.message); | ||
} else { | ||
@@ -155,9 +132,38 @@ messages.push(cause); | ||
key: 'cause', | ||
get: function get() { | ||
return this.___trace_error_causes__[0]; | ||
value: function cause() { | ||
var index = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; | ||
return this._getProperty('causes', [])[index]; | ||
} | ||
}, { | ||
key: 'causes', | ||
value: function causes() { | ||
return this._getProperty('causes', []); | ||
} | ||
}, { | ||
key: '_defineProperty', | ||
value: function _defineProperty(key, value) { | ||
var pr = privates.has(this) ? privates.get(this) : {}; | ||
pr[key] = value; | ||
privates.set(this, pr); | ||
} | ||
}, { | ||
key: '_getProperty', | ||
value: function _getProperty(key, def) { | ||
return privates.has(this) ? privates.get(this)[key] : def; | ||
} | ||
}, { | ||
key: 'stack', | ||
get: function get() { | ||
return this.___trace_error_causes__; | ||
if (this._getProperty('useBase', false)) { | ||
return _get(Object.getPrototypeOf(TraceError.prototype), 'stack', this); | ||
} | ||
this._defineProperty('useBase', true); | ||
var stack = this.getLongStack(); | ||
this._defineProperty('useBase', false); | ||
return stack; | ||
} | ||
@@ -167,2 +173,6 @@ }]); | ||
function TraceError(message) { | ||
_classCallCheck(this, TraceError); | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(TraceError).call(this, message)); | ||
for (var _len = arguments.length, causes = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
@@ -172,7 +182,3 @@ causes[_key - 1] = arguments[_key]; | ||
_classCallCheck(this, TraceError); | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(TraceError).call(this, message)); | ||
Object.defineProperty(_this, '___trace_error_causes__', { value: causes }); | ||
_this._defineProperty('causes', causes); | ||
return _this; | ||
@@ -179,0 +185,0 @@ } |
{ | ||
"name": "trace-error", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Chained errors for JavaScript", | ||
@@ -33,3 +33,6 @@ "main": "index.js", | ||
"mocha": "2.4.5" | ||
}, | ||
"dependencies": { | ||
"weakmap": "0.0.6" | ||
} | ||
} |
@@ -31,8 +31,2 @@ # TraceError | ||
#### `TraceError@cause` | ||
Get the cause at first index | ||
#### `TraceError@causes` | ||
Get a list of all the causes | ||
#### `TraceError@stack` | ||
@@ -52,2 +46,17 @@ Get the long stack (base error with chained cause errors) | ||
More detailed examples are in the `/tests` folder | ||
More detailed examples are in the `/tests` folder | ||
### ES5/6 Cross-compatibility | ||
Extend the TraceError as such in order to maximize compatibility with ES5 | ||
```js | ||
export class MyAppTraceError extends TraceError { | ||
constructor(...args) { | ||
super(...args); | ||
Object.defineProperty(this, 'stack', { | ||
get: () => super.stack | ||
}); | ||
} | ||
} | ||
``` |
@@ -0,21 +1,35 @@ | ||
import WeakMap from 'weakmap'; | ||
const privates = new WeakMap(); | ||
export default class Exception { | ||
get stack() { | ||
return this.___base_exception___.stack; | ||
return this._getProperty('error', {}).stack; | ||
} | ||
get name() { | ||
return this.___base_exception___.name; | ||
return this._getProperty('error', {}).name; | ||
} | ||
get message() { | ||
return this.___base_exception___.message; | ||
return this._getProperty('error', {}).message; | ||
} | ||
get(key) { | ||
return this.___base_exception___[key]; | ||
return this._getProperty('error', {})[key]; | ||
} | ||
_defineProperty(key, value) { | ||
const pr = privates.has(this) ? privates.get(this) : {}; | ||
pr[key] = value; | ||
privates.set(this, pr); | ||
} | ||
_getProperty(key, def) { | ||
return privates.has(this) ? privates.get(this)[key] : def; | ||
} | ||
constructor(...args) { | ||
const error = new Error(...args); | ||
Object.defineProperty(this, '___base_exception___', {configurable: false, value: error, enumerable: false}); | ||
this._defineProperty('error', error); | ||
} | ||
@@ -22,0 +36,0 @@ } |
import Exception from './Exception'; | ||
import WeakMap from 'weakmap'; | ||
const privates = new WeakMap(); | ||
export default class TraceError extends Exception { | ||
@@ -25,3 +28,3 @@ static indent = ' '; | ||
for (const cause of this.causes) { | ||
for (const cause of this.causes()) { | ||
if (cause instanceof TraceError) { | ||
@@ -41,10 +44,11 @@ stacks.push(cause.getLongStack()) | ||
get stack() { | ||
if (this.___trace_error_use_base___) { | ||
if (this._getProperty('useBase', false)) { | ||
return super.stack; | ||
} | ||
Object.defineProperty(this, '___trace_error_use_base___', {value: true, configurable: true, enumerable: false}); | ||
this._defineProperty('useBase', true); | ||
const stack = this.getLongStack(); | ||
Object.defineProperty(this, '___trace_error_use_base___', {value: false, configurable: true, enumerable: false}); | ||
this._defineProperty('useBase', false); | ||
@@ -54,13 +58,10 @@ return stack; | ||
get messages() { | ||
messages() { | ||
let messages = [super.message]; | ||
for (const cause of this.causes) { | ||
if (cause instanceof Error) { | ||
const message = cause.messages || cause.message; | ||
if (Array.isArray(message)) { | ||
messages = messages.concat(message); | ||
} else { | ||
messages.push(message); | ||
} | ||
for (const cause of this.causes()) { | ||
if (cause instanceof TraceError) { | ||
messages = messages.concat(cause.messages()); | ||
} else if (cause instanceof Error) { | ||
messages.push(cause.message); | ||
} else { | ||
@@ -75,16 +76,17 @@ messages.push(cause); | ||
cause(index = 0) { | ||
return this.___trace_error_causes__[index]; | ||
return this._getProperty('causes', [])[index]; | ||
} | ||
causes() { | ||
return this.___trace_error_causes__; | ||
return this._getProperty('causes', []); | ||
} | ||
get cause() { | ||
return this.___trace_error_causes__[0]; | ||
_defineProperty(key, value) { | ||
const pr = privates.has(this) ? privates.get(this) : {}; | ||
pr[key] = value; | ||
privates.set(this, pr); | ||
} | ||
get causes() { | ||
return this.___trace_error_causes__; | ||
_getProperty(key, def) { | ||
return privates.has(this) ? privates.get(this)[key] : def; | ||
} | ||
@@ -95,4 +97,4 @@ | ||
Object.defineProperty(this, '___trace_error_causes__', {value: causes, enumerable: false, configurable: false}); | ||
this._defineProperty('causes', causes); | ||
} | ||
} |
@@ -7,2 +7,55 @@ var TraceError = require('../'); | ||
describe('TraceError', function () { | ||
it('should be able to access the property names; overridable with toJSON', function () { | ||
Error.prototype.toJSON = function () { | ||
var alt = {}; | ||
var proto = this; | ||
var chain = [proto]; | ||
while (proto = Object.getPrototypeOf(proto)) { | ||
chain.push(proto); | ||
} | ||
for (var i = 0; i < chain.length; i++) { | ||
var _proto = chain[i]; | ||
var storeKey = function (key) { | ||
if (alt.hasOwnProperty(key)) return; | ||
var desc = Object.getOwnPropertyDescriptor(_proto, key); | ||
if (desc) { | ||
var value = desc.get ? desc.get.call(this) : desc.value; | ||
// avoid the proto keys | ||
if (_proto.isPrototypeOf(value)) { | ||
return; | ||
} | ||
// avoid the base class name | ||
if (key === 'name' && value === 'Error') { | ||
return; | ||
} | ||
if (typeof value !== 'function') { | ||
// assume message is duped in stack | ||
if (key === 'message') return; | ||
if (key === 'stack') { | ||
if (value.indexOf('Error: ') === 0) | ||
value = value.substr(7); | ||
key = 'Error'; | ||
} | ||
alt[key] = value; | ||
} | ||
} | ||
}; | ||
Object.getOwnPropertyNames(_proto).forEach(storeKey, this); | ||
} | ||
return alt; | ||
}; | ||
assert.deepEqual(Object.keys(new TraceError('sup').toJSON()), Object.keys(new Error('sup').toJSON())); | ||
assert.equal(Object.keys(new TraceError('sup').toJSON()).length, 1); | ||
}); | ||
it('should chain multiple errors across different levels', function () { | ||
@@ -16,8 +69,8 @@ try { | ||
} catch (e) { | ||
assert.deepEqual(e.messages, ['Captured', {test: 5}, 'Test error', 'Test cause', {error: 'test'}]); | ||
assert.deepEqual(e.messages(), ['Captured', {test: 5}, 'Test error', 'Test cause', {error: 'test'}]); | ||
assert.equal(e.message, 'Captured'); | ||
assert.equal(e.cause.test, 5); | ||
assert.equal(e.causes[1].message, 'Test error'); | ||
assert.equal(e.causes[1].cause.message, 'Test cause'); | ||
assert.equal(e.causes[1].causes[1].error, 'test'); | ||
assert.equal(e.cause().test, 5); | ||
assert.equal(e.cause(1).message, 'Test error'); | ||
assert.equal(e.cause(1).cause().message, 'Test cause'); | ||
assert.equal(e.cause(1).cause(1).error, 'test'); | ||
} | ||
@@ -49,9 +102,2 @@ }); | ||
} catch (e) { | ||
assert.deepEqual(e.messages, ['Captured', {test: 5}, 'Test error', 'Test cause', {error: 'test'}]); | ||
assert.equal(e.message, 'Captured'); | ||
assert.equal(e.cause.test, 5); | ||
assert.equal(e.causes[1].message, 'Test error'); | ||
assert.equal(e.causes[1].cause.message, 'Test cause'); | ||
assert.equal(e.causes[1].causes[1].error, 'test'); | ||
assert.equal(e.stack, fs.readFileSync(path.join(__dirname, 'custom-stack-1.txt'), 'utf8')); | ||
@@ -58,0 +104,0 @@ } |
19636
432
60
1
+ Addedweakmap@0.0.6
+ Addedweakmap@0.0.6(transitive)