| 'use strict'; | |
| var util = require('util'); | |
| var isArrayish = require('is-arrayish'); | |
| var errorEx = function errorEx(name, properties) { | |
| if (!name || name.constructor !== String) { | |
| properties = name || {}; | |
| name = Error.name; | |
| } | |
| var errorExError = function ErrorEXError(message) { | |
| if (!this) { | |
| return new ErrorEXError(message); | |
| } | |
| message = message instanceof Error | |
| ? message.message | |
| : (message || this.message); | |
| Error.call(this, message); | |
| Error.captureStackTrace(this, errorExError); | |
| this.name = name; | |
| Object.defineProperty(this, 'message', { | |
| configurable: true, | |
| enumerable: false, | |
| get: function () { | |
| var newMessage = message.split(/\r?\n/g); | |
| for (var key in properties) { | |
| if (!properties.hasOwnProperty(key)) { | |
| continue; | |
| } | |
| var modifier = properties[key]; | |
| if ('message' in modifier) { | |
| newMessage = modifier.message(this[key], newMessage) || newMessage; | |
| if (!isArrayish(newMessage)) { | |
| newMessage = [newMessage]; | |
| } | |
| } | |
| } | |
| return newMessage.join('\n'); | |
| }, | |
| set: function (v) { | |
| message = v; | |
| } | |
| }); | |
| var overwrittenStack = null; | |
| var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); | |
| var stackGetter = stackDescriptor.get; | |
| var stackValue = stackDescriptor.value; | |
| delete stackDescriptor.value; | |
| delete stackDescriptor.writable; | |
| stackDescriptor.set = function (newstack) { | |
| overwrittenStack = newstack; | |
| }; | |
| stackDescriptor.get = function () { | |
| var stack = (overwrittenStack || ((stackGetter) | |
| ? stackGetter.call(this) | |
| : stackValue)).split(/\r?\n+/g); | |
| // starting in Node 7, the stack builder caches the message. | |
| // just replace it. | |
| if (!overwrittenStack) { | |
| stack[0] = this.name + ': ' + this.message; | |
| } | |
| var lineCount = 1; | |
| for (var key in properties) { | |
| if (!properties.hasOwnProperty(key)) { | |
| continue; | |
| } | |
| var modifier = properties[key]; | |
| if ('line' in modifier) { | |
| var line = modifier.line(this[key]); | |
| if (line) { | |
| stack.splice(lineCount++, 0, ' ' + line); | |
| } | |
| } | |
| if ('stack' in modifier) { | |
| modifier.stack(this[key], stack); | |
| } | |
| } | |
| return stack.join('\n'); | |
| }; | |
| Object.defineProperty(this, 'stack', stackDescriptor); | |
| }; | |
| if (Object.setPrototypeOf) { | |
| Object.setPrototypeOf(errorExError.prototype, Error.prototype); | |
| Object.setPrototypeOf(errorExError, Error); | |
| } else { | |
| util.inherits(errorExError, Error); | |
| } | |
| return errorExError; | |
| }; | |
| errorEx.append = function (str, def) { | |
| return { | |
| message: function (v, message) { | |
| v = v || def; | |
| if (v) { | |
| message[0] += ' ' + str.replace('%s', v.toString()); | |
| } | |
| return message; | |
| } | |
| }; | |
| }; | |
| errorEx.line = function (str, def) { | |
| return { | |
| line: function (v) { | |
| v = v || def; | |
| if (v) { | |
| return str.replace('%s', v.toString()); | |
| } | |
| return null; | |
| } | |
| }; | |
| }; | |
| module.exports = errorEx; |