123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- var tmpl = require('tmpl')
-
- module.exports = makeError
-
- function BaseError() {}
- BaseError.prototype = new Error()
- BaseError.prototype.toString = function() {
- return this.message
- }
-
-
- /**
- * Makes an Error function with the signature:
- *
- * function(message, data)
- *
- * You'll typically do something like:
- *
- * var UnknownFileTypeError = makeError(
- * 'UnknownFileTypeError',
- * 'The specified type is not known.'
- * )
- * var er = UnknownFileTypeError()
- *
- * `er` will have a prototype chain that ensures:
- *
- * er instanceof Error
- * er instanceof UnknownFileTypeError
- *
- * You can also do `var er = new UnknownFileTypeError()` if you really like the
- * `new` keyword.
- *
- * @param String The name of the error.
- * @param String The default message string.
- * @param Object The default data object, merged with per instance data.
- */
- function makeError(name, defaultMessage, defaultData) {
- defaultMessage = tmpl(defaultMessage || '')
- defaultData = defaultData || {}
- if (defaultData.proto && !(defaultData.proto instanceof BaseError))
- throw new Error('The custom "proto" must be an Error created via makeError')
-
- var CustomError = function(message, data) {
- if (!(this instanceof CustomError)) return new CustomError(message, data)
-
- if (typeof message !== 'string' && !data) {
- data = message
- message = null
- }
-
- this.name = name
- this.data = data || defaultData
-
- if (typeof message === 'string') {
- this.message = tmpl(message, this.data)
- } else {
- this.message = defaultMessage(this.data)
- }
-
- var er = new Error()
- this.stack = er.stack
- if (this.stack) {
- // remove TWO stack level:
- if (typeof Components !== 'undefined') {
- // Mozilla:
- this.stack = this.stack.substring(this.stack.indexOf('\n') + 2)
- } else if (typeof chrome !== 'undefined' || typeof process !== 'undefined') {
- // Google Chrome/Node.js:
- this.stack = this.stack.replace(/\n[^\n]*/, '')
- this.stack = this.stack.replace(/\n[^\n]*/, '')
- this.stack = (
- this.name +
- (this.message ? (': ' + this.message) : '') +
- this.stack.substring(5)
- )
- }
- }
-
- if ('fileName' in er) this.fileName = er.fileName
- if ('lineNumber' in er) this.lineNumber = er.lineNumber
- }
-
- CustomError.prototype = defaultData.proto || new BaseError()
- delete defaultData.proto
-
- return CustomError
- }
|