152 lines
3.8 KiB
JavaScript
152 lines
3.8 KiB
JavaScript
|
// 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()`.
|
||
|
//
|
||
|
// eslint-disable-next-line dot-notation
|
||
|
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;
|