142 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			142 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | '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; |