3 var util = require('util');
4 var isArrayish = require('is-arrayish');
6 var errorEx = function errorEx(name, properties) {
7 if (!name || name.constructor !== String) {
8 properties = name || {};
12 var errorExError = function ErrorEXError(message) {
14 return new ErrorEXError(message);
17 message = message instanceof Error
19 : (message || this.message);
21 Error.call(this, message);
22 Error.captureStackTrace(this, errorExError);
26 Object.defineProperty(this, 'message', {
30 var newMessage = message.split(/\r?\n/g);
32 for (var key in properties) {
33 if (!properties.hasOwnProperty(key)) {
37 var modifier = properties[key];
39 if ('message' in modifier) {
40 newMessage = modifier.message(this[key], newMessage) || newMessage;
41 if (!isArrayish(newMessage)) {
42 newMessage = [newMessage];
47 return newMessage.join('\n');
54 var overwrittenStack = null;
56 var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack');
57 var stackGetter = stackDescriptor.get;
58 var stackValue = stackDescriptor.value;
59 delete stackDescriptor.value;
60 delete stackDescriptor.writable;
62 stackDescriptor.set = function (newstack) {
63 overwrittenStack = newstack;
66 stackDescriptor.get = function () {
67 var stack = (overwrittenStack || ((stackGetter)
68 ? stackGetter.call(this)
69 : stackValue)).split(/\r?\n+/g);
71 // starting in Node 7, the stack builder caches the message.
73 if (!overwrittenStack) {
74 stack[0] = this.name + ': ' + this.message;
78 for (var key in properties) {
79 if (!properties.hasOwnProperty(key)) {
83 var modifier = properties[key];
85 if ('line' in modifier) {
86 var line = modifier.line(this[key]);
88 stack.splice(lineCount++, 0, ' ' + line);
92 if ('stack' in modifier) {
93 modifier.stack(this[key], stack);
97 return stack.join('\n');
100 Object.defineProperty(this, 'stack', stackDescriptor);
103 if (Object.setPrototypeOf) {
104 Object.setPrototypeOf(errorExError.prototype, Error.prototype);
105 Object.setPrototypeOf(errorExError, Error);
107 util.inherits(errorExError, Error);
113 errorEx.append = function (str, def) {
115 message: function (v, message) {
119 message[0] += ' ' + str.replace('%s', v.toString());
127 errorEx.line = function (str, def) {
133 return str.replace('%s', v.toString());
141 module.exports = errorEx;