// ISC @ Julien Fontanet 'use strict' // =================================================================== var construct = typeof Reflect !== 'undefined' ? Reflect.construct : undefined var defineProperty = Object.defineProperty // ------------------------------------------------------------------- var captureStackTrace = Error.captureStackTrace if (captureStackTrace === undefined) { captureStackTrace = function captureStackTrace (error) { var container = new Error() defineProperty(error, 'stack', { configurable: true, get: function getStack () { var stack = container.stack // Replace property with value for faster future accesses. defineProperty(this, 'stack', { configurable: true, value: stack, writable: true }) return stack }, set: function setStack (stack) { defineProperty(error, 'stack', { configurable: true, value: stack, writable: true }) } }) } } // ------------------------------------------------------------------- function BaseError (message) { if (message !== undefined) { defineProperty(this, 'message', { configurable: true, value: message, writable: true }) } var cname = this.constructor.name if ( cname !== undefined && cname !== this.name ) { defineProperty(this, 'name', { configurable: true, value: cname, writable: true }) } captureStackTrace(this, this.constructor) } BaseError.prototype = Object.create(Error.prototype, { // See: https://github.com/JsCommunity/make-error/issues/4 constructor: { configurable: true, value: BaseError, writable: true } }) // ------------------------------------------------------------------- // Sets the name of a function if possible (depends of the JS engine). var setFunctionName = (function () { function setFunctionName (fn, name) { return defineProperty(fn, 'name', { configurable: true, value: name }) } try { var f = function () {} setFunctionName(f, 'foo') if (f.name === 'foo') { return setFunctionName } } catch (_) {} })() // ------------------------------------------------------------------- function makeError (constructor, super_) { if (super_ == null || super_ === Error) { super_ = BaseError } else if (typeof super_ !== 'function') { throw new TypeError('super_ should be a function') } var name if (typeof constructor === 'string') { name = constructor constructor = construct !== undefined ? function () { return construct(super_, arguments, this.constructor) } : function () { super_.apply(this, arguments) } // If the name can be set, do it once and for all. if (setFunctionName !== undefined) { setFunctionName(constructor, name) name = undefined } } else if (typeof constructor !== 'function') { throw new TypeError('constructor should be either a string or a function') } // Also register the super constructor also as `constructor.super_` just // like Node's `util.inherits()`. constructor.super_ = constructor['super'] = super_ var properties = { constructor: { configurable: true, value: constructor, writable: true } } // If the name could not be set on the constructor, set it on the // prototype. if (name !== undefined) { properties.name = { configurable: true, value: name, writable: true } } constructor.prototype = Object.create(super_.prototype, properties) return constructor } exports = module.exports = makeError exports.BaseError = BaseError