123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // 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
|