diff options
Diffstat (limited to 'node_modules/pretty-error/src')
-rw-r--r-- | node_modules/pretty-error/src/ParsedError.coffee | 226 | ||||
-rw-r--r-- | node_modules/pretty-error/src/PrettyError.coffee | 312 | ||||
-rw-r--r-- | node_modules/pretty-error/src/defaultStyle.coffee | 59 | ||||
-rw-r--r-- | node_modules/pretty-error/src/nodePaths.coffee | 52 |
4 files changed, 649 insertions, 0 deletions
diff --git a/node_modules/pretty-error/src/ParsedError.coffee b/node_modules/pretty-error/src/ParsedError.coffee new file mode 100644 index 000000000..cced61dd5 --- /dev/null +++ b/node_modules/pretty-error/src/ParsedError.coffee @@ -0,0 +1,226 @@ +sysPath = require 'path' + +module.exports = class ParsedError + constructor: (@error) -> + do @_parse + + _parse: -> + @_trace = [] + @_kind = 'Error' + @_wrapper = '' + + @_wrapper = String @error.wrapper if @error.wrapper? + + unless typeof @error is 'object' + @_message = String @error + else + @_stack = @error.stack + + if @error.kind? + @_kind = String @error.kind + else if typeof @_stack is 'string' + if m = @_stack.match /^([a-zA-Z0-9\_\$]+):\ / + @_kind = m[1] + + if typeof @_stack is 'string' + @_parseStack() + else + @_message = @error.message? and String(@error.message) or '' + + return + + _parseStack: -> + messageLines = [] + reachedTrace = no + + for line in @_stack.split '\n' + continue if line.trim() is '' + if reachedTrace + @_trace.push @_parseTraceItem line + else + if line.match /^\s*at\s.+/ + reachedTrace = yes + @_trace.push @_parseTraceItem line + else + messageLines.push line + + message = messageLines.join '\n' + if message.substr(0, @_kind.length) is @_kind + message = + message + .substr(@_kind.length, message.length) + .replace(/^\:\s+/, '') + + @_message = message + + return + + _parseTraceItem: (text) -> + text = text.trim() + + return if text is '' + return text unless text.match /^at\ / + + # remove the 'at ' part + text = text.replace /^at /, '' + + return if text in ['Error (<anonymous>)', 'Error (<anonymous>:null:null)'] + + original = text + + # the part that comes before the address + what = null + + # address, including path to module and line/col + addr = null + + # path to module + path = null + + # module dir + dir = null + + # module basename + file = null + + # line number (if using a compiler, the line number of the module + # in that compiler will be used) + line = null + + # column, same as above + col = null + + # if using a compiler, this will translate to the line number of + # the js equivalent of that module + jsLine = null + + # like above + jsCol = null + + # path that doesn't include `node_module` dirs + shortenedPath = null + + # like above + shortenedAddr = null + + packageName = '[current]' + + # pick out the address + if m = text.match /\(([^\)]+)\)$/ + addr = m[1].trim() + + if addr? + what = text.substr 0, text.length - addr.length - 2 + what = what.trim() + + # might not have a 'what' clause + unless addr? + addr = text.trim() + + addr = @_fixPath addr + remaining = addr + + # remove the <js> clause if the file is a compiled one + if m = remaining.match /\,\ <js>:(\d+):(\d+)$/ + jsLine = m[1] + jsCol = m[2] + remaining = remaining.substr 0, remaining.length - m[0].length + + # the line/col part + if m = remaining.match /:(\d+):(\d+)$/ + line = m[1] + col = m[2] + remaining = remaining.substr 0, remaining.length - m[0].length + path = remaining + + # file and dir + if path? + file = sysPath.basename path + dir = sysPath.dirname path + + if dir is '.' then dir = '' + + path = @_fixPath path + file = @_fixPath file + dir = @_fixPath dir + + if dir? + d = dir.replace /[\\]{1,2}/g, '/' + if m = d.match /// + node_modules/([^/]+)(?!.*node_modules.*) + /// + + packageName = m[1] + + unless jsLine? + jsLine = line + jsCol = col + + if path? + r = @_rectifyPath path + shortenedPath = r.path + shortenedAddr = shortenedPath + addr.substr(path.length, addr.length) + packages = r.packages + + original: original + what: what + addr: addr + path: path + dir: dir + file: file + line: parseInt line + col: parseInt col + jsLine: parseInt jsLine + jsCol: parseInt jsCol + packageName: packageName + shortenedPath: shortenedPath + shortenedAddr: shortenedAddr + packages: packages || [] + + _getMessage: -> @_message + _getKind: -> @_kind + _getWrapper: -> @_wrapper + _getStack: -> @_stack + _getArguments: -> @error.arguments + _getType: -> @error.type + _getTrace: -> @_trace + _fixPath: (path) -> path.replace(///[\\]{1,2}///g, '/') + + _rectifyPath: (path, nameForCurrentPackage) -> + path = String path + remaining = path + + return path: path, packages: [] unless m = path.match /^(.+?)\/node_modules\/(.+)$/ + + parts = [] + packages = [] + + if typeof nameForCurrentPackage is 'string' + parts.push "[#{nameForCurrentPackage}]" + packages.push "[#{nameForCurrentPackage}]" + else + parts.push "[#{m[1].match(/([^\/]+)$/)[1]}]" + packages.push m[1].match(/([^\/]+)$/)[1] + + rest = m[2] + + while m = rest.match /([^\/]+)\/node_modules\/(.+)$/ + parts.push "[#{m[1]}]" + packages.push m[1] + rest = m[2] + + if m = rest.match /([^\/]+)\/(.+)$/ + parts.push "[#{m[1]}]" + packages.push m[1] + rest = m[2] + + parts.push rest + + path: parts.join "/" + packages: packages + +for prop in ['message', 'kind', 'arguments', 'type', 'stack', 'trace', 'wrapper'] then do -> + methodName = '_get' + prop[0].toUpperCase() + prop.substr(1, prop.length) + + Object.defineProperty ParsedError::, prop, + get: -> this[methodName]()
\ No newline at end of file diff --git a/node_modules/pretty-error/src/PrettyError.coffee b/node_modules/pretty-error/src/PrettyError.coffee new file mode 100644 index 000000000..dc44943af --- /dev/null +++ b/node_modules/pretty-error/src/PrettyError.coffee @@ -0,0 +1,312 @@ +{object, array} = require 'utila' +defaultStyle = require './defaultStyle' +ParsedError = require './ParsedError' +nodePaths = require './nodePaths' +RenderKid = require 'renderkid' + +instance = null + +module.exports = class PrettyError + self = @ + + @_filters: + 'module.exports': (item) -> + return unless item.what? + item.what = item.what.replace /\.module\.exports\./g, ' - ' + return + + @_getDefaultStyle: -> + defaultStyle() + + @start: -> + unless instance? + instance = new self + instance.start() + + instance + + @stop: -> + instance?.stop() + + constructor: -> + @_useColors = yes + @_maxItems = 50 + @_packagesToSkip = [] + @_pathsToSkip = [] + @_skipCallbacks = [] + @_filterCallbacks = [] + @_parsedErrorFilters = [] + @_aliases = [] + @_renderer = new RenderKid + @_style = self._getDefaultStyle() + @_renderer.style @_style + + start: -> + @_oldPrepareStackTrace = Error.prepareStackTrace + + prepeare = @_oldPrepareStackTrace or (exc, frames) -> + result = exc.toString() + frames = frames.map (frame) -> " at #{frame.toString()}" + result + "\n" + frames.join "\n" + + # https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + Error.prepareStackTrace = (exc, trace) => + stack = prepeare.apply(null, arguments) + @render {stack, message: exc.toString().replace /^.*: /, ''}, no + + @ + + stop: -> + Error.prepareStackTrace = @_oldPrepareStackTrace + @_oldPrepareStackTrace = null + + config: (c) -> + if c.skipPackages? + if c.skipPackages is no + @unskipAllPackages() + else + @skipPackage.apply @, c.skipPackages + + if c.skipPaths? + if c.skipPaths is no + @unskipAllPaths() + else + @skipPath.apply @, c.skipPaths + + if c.skip? + if c.skip is no + @unskipAll() + else + @skip.apply @, c.skip + + if c.maxItems? + @setMaxItems c.maxItems + + if c.skipNodeFiles is yes + @skipNodeFiles() + else if c.skipNodeFiles is no + @unskipNodeFiles() + + if c.filters? + if c.filters is no + @removeAllFilters() + else + @filter.apply @, c.filters + + if c.parsedErrorFilters? + if c.parsedErrorFilters is no + @removeAllParsedErrorFilters() + else + @filterParsedError.apply @, c.parsedErrorFilters + + if c.aliases? + if object.isBareObject c.aliases + @alias path, alias for path, alias of c.aliases + else if c.aliases is no + @removeAllAliases() + + @ + + withoutColors: -> + @_useColors = false + @ + + withColors: -> + @_useColors = true + @ + + skipPackage: (packages...) -> + @_packagesToSkip.push String pkg for pkg in packages + @ + + unskipPackage: (packages...) -> + array.pluckOneItem(@_packagesToSkip, pkg) for pkg in packages + @ + + unskipAllPackages: -> + @_packagesToSkip.length = 0 + @ + + skipPath: (paths...) -> + @_pathsToSkip.push path for path in paths + @ + + unskipPath: (paths...) -> + array.pluckOneItem(@_pathsToSkip, path) for path in paths + @ + + unskipAllPaths: -> + @_pathsToSkip.length = 0 + @ + + skip: (callbacks...) -> + @_skipCallbacks.push cb for cb in callbacks + @ + + unskip: (callbacks...) -> + array.pluckOneItem(@_skipCallbacks, cb) for cb in callbacks + @ + + unskipAll: -> + @_skipCallbacks.length = 0 + @ + + skipNodeFiles: -> + @skipPath.apply @, nodePaths + + unskipNodeFiles: -> + @unskipPath.apply @, nodePaths + + filter: (callbacks...) -> + @_filterCallbacks.push cb for cb in callbacks + @ + + removeFilter: (callbacks...) -> + array.pluckOneItem(@_filterCallbacks, cb) for cb in callbacks + @ + + removeAllFilters: -> + @_filterCallbacks.length = 0 + @ + + filterParsedError: (callbacks...) -> + @_parsedErrorFilters.push cb for cb in callbacks + @ + + removeParsedErrorFilter: (callbacks...) -> + array.pluckOneItem(@_parsedErrorFilters, cb) for cb in callbacks + @ + + removeAllParsedErrorFilters: -> + @_parsedErrorFilters.length = 0 + @ + + setMaxItems: (maxItems = 50) -> + if maxItems is 0 then maxItems = 50 + @_maxItems = maxItems|0 + @ + + alias: (stringOrRx, alias) -> + @_aliases.push {stringOrRx, alias} + @ + + removeAlias: (stringOrRx) -> + array.pluckByCallback @_aliases, (pair) -> + pair.stringOrRx is stringOrRx + + @ + + removeAllAliases: -> + @_aliases.length = 0 + @ + + _getStyle: -> + @_style + + appendStyle: (toAppend) -> + object.appendOnto @_style, toAppend + @_renderer.style toAppend + @ + + _getRenderer: -> + @_renderer + + render: (e, logIt = no, useColors = @_useColors) -> + obj = @getObject e + rendered = @_renderer.render(obj, useColors) + console.error rendered if logIt is yes + rendered + + getObject: (e) -> + unless e instanceof ParsedError + e = new ParsedError e + + @_applyParsedErrorFiltersOn e + + header = + title: do -> + ret = {} + + # some errors are thrown to display other errors. + # we call them wrappers here. + if e.wrapper isnt '' + ret.wrapper = "#{e.wrapper}" + + ret.kind = e.kind + ret + + colon: ':' + + message: String(e.message).trim() + + traceItems = [] + count = -1 + + for item, i in e.trace + continue unless item? + continue if @_skipOrFilter(item, i) is yes + + count++ + + break if count > @_maxItems + + if typeof item is 'string' + traceItems.push item: custom: item + continue + + traceItems.push do -> + markupItem = item: + header: + pointer: do -> + return '' unless item.file? + + file: item.file + colon: ':' + line: item.line + + footer: do -> + foooter = addr: item.shortenedAddr + if item.extra? then foooter.extra = item.extra + foooter + + markupItem.item.header.what = item.what if typeof item.what is 'string' and item.what.trim().length > 0 + markupItem + + + obj = 'pretty-error': + header: header + + if traceItems.length > 0 + obj['pretty-error'].trace = traceItems + + obj + + _skipOrFilter: (item, itemNumber) -> + if typeof item is 'object' + return yes if item.modName in @_packagesToSkip + return yes if item.path in @_pathsToSkip + + for modName in item.packages + return yes if modName in @_packagesToSkip + + if typeof item.shortenedAddr is 'string' + for pair in @_aliases + item.shortenedAddr = item.shortenedAddr.replace pair.stringOrRx, pair.alias + + for cb in @_skipCallbacks + return yes if cb(item, itemNumber) is yes + + for cb in @_filterCallbacks + cb(item, itemNumber) + + return no + + _applyParsedErrorFiltersOn: (error) -> + for cb in @_parsedErrorFilters + cb error + + return + +for prop in ['renderer', 'style'] then do -> + methodName = '_get' + prop[0].toUpperCase() + prop.substr(1, prop.length) + PrettyError::__defineGetter__ prop, -> do @[methodName] diff --git a/node_modules/pretty-error/src/defaultStyle.coffee b/node_modules/pretty-error/src/defaultStyle.coffee new file mode 100644 index 000000000..95cd2ac28 --- /dev/null +++ b/node_modules/pretty-error/src/defaultStyle.coffee @@ -0,0 +1,59 @@ +module.exports = -> + 'pretty-error': + display: 'block' + marginLeft: '2' + + 'pretty-error > header': + display: 'block' + + 'pretty-error > header > title > kind': + background: 'red' + color: 'bright-white' + + 'pretty-error > header > title > wrapper': + marginRight: '1' + color: 'grey' + + 'pretty-error > header > colon': + color: 'grey' + marginRight: 1 + + 'pretty-error > header > message': + color: 'bright-white' + + 'pretty-error > trace': + display: 'block' + marginTop: 1 + + 'pretty-error > trace > item': + display: 'block' + marginBottom: 1 + marginLeft: 2 + bullet: '"<grey>-</grey>"' + + 'pretty-error > trace > item > header': + display: 'block' + + 'pretty-error > trace > item > header > pointer > file': + color: 'bright-yellow' + + 'pretty-error > trace > item > header > pointer > colon': + color: 'grey' + + 'pretty-error > trace > item > header > pointer > line': + color: 'bright-yellow' + marginRight: 1 + + 'pretty-error > trace > item > header > what': + color: 'white' + + 'pretty-error > trace > item > footer': + display: 'block' + + 'pretty-error > trace > item > footer > addr': + display: 'block' + color: 'grey' + + 'pretty-error > trace > item > footer > extra': + display: 'block' + color: 'grey' diff --git a/node_modules/pretty-error/src/nodePaths.coffee b/node_modules/pretty-error/src/nodePaths.coffee new file mode 100644 index 000000000..32ed832ae --- /dev/null +++ b/node_modules/pretty-error/src/nodePaths.coffee @@ -0,0 +1,52 @@ +module.exports = [ + '_debugger.js' + '_http_agent.js' + '_http_client.js' + '_http_common.js' + '_http_incoming.js' + '_http_outgoing.js' + '_http_server.js' + '_linklist.js' + '_stream_duplex.js' + '_stream_passthrough.js' + '_stream_readable.js' + '_stream_transform.js' + '_stream_writable.js' + '_tls_legacy.js' + '_tls_wrap.js' + 'assert.js' + 'buffer.js' + 'child_process.js' + 'cluster.js' + 'console.js' + 'constants.js' + 'crypto.js' + 'dgram.js' + 'dns.js' + 'domain.js' + 'events.js' + 'freelist.js' + 'fs.js' + 'http.js' + 'https.js' + 'module.js' + 'net.js' + 'os.js' + 'path.js' + 'punycode.js' + 'querystring.js' + 'readline.js' + 'repl.js' + 'smalloc.js' + 'stream.js' + 'string_decoder.js' + 'sys.js' + 'timers.js' + 'tls.js' + 'tty.js' + 'url.js' + 'util.js' + 'vm.js' + 'zlib.js' + 'node.js' +]
\ No newline at end of file |