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 stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack');
55 var stackGetter = stackDescriptor.get;
56 var stackValue = stackDescriptor.value;
57 delete stackDescriptor.value;
58 delete stackDescriptor.writable;
60 stackDescriptor.get = function () {
61 var stack = (stackGetter)
62 ? stackGetter.call(this).split(/\r?\n+/g)
63 : stackValue.split(/\r?\n+/g);
65 // starting in Node 7, the stack builder caches the message.
67 stack[0] = this.name + ': ' + this.message;
70 for (var key in properties) {
71 if (!properties.hasOwnProperty(key)) {
75 var modifier = properties[key];
77 if ('line' in modifier) {
78 var line = modifier.line(this[key]);
80 stack.splice(lineCount++, 0, ' ' + line);
84 if ('stack' in modifier) {
85 modifier.stack(this[key], stack);
89 return stack.join('\n');
92 Object.defineProperty(this, 'stack', stackDescriptor);
95 if (Object.setPrototypeOf) {
96 Object.setPrototypeOf(errorExError.prototype, Error.prototype);
97 Object.setPrototypeOf(errorExError, Error);
99 util.inherits(errorExError, Error);
105 errorEx.append = function (str, def) {
107 message: function (v, message) {
111 message[0] += ' ' + str.replace('%s', v.toString());
119 errorEx.line = function (str, def) {
125 return str.replace('%s', v.toString());
133 module.exports = errorEx;