Comparing version 0.1.0 to 0.2.0
190
index.js
require('tinycolor'); | ||
var util = require('util'); | ||
var pkgLookup = require('package-lookup'); | ||
var nodeVersion = process.version.replace(/^v/, ''); | ||
var chain; | ||
try { | ||
chain = require('stack-chain'); | ||
} catch (error) {} | ||
if (chain) { | ||
chain.format.replace(function(error, frames) { | ||
return formatStack(error, { callSite: frames }); | ||
}); | ||
} | ||
function underscoreName(identifier) { | ||
@@ -16,2 +30,21 @@ return identifier.replace(/[A-Z][a-z]+/g, function(part) { | ||
function lookupPackage(filename) { | ||
if (/^\//.test(filename)) { | ||
var pkg = pkgLookup.resolve(filename); | ||
if (pkg) { | ||
return { | ||
name: ('' + [pkg.name]) || null, | ||
version: ('' + [pkg.version]) || null, | ||
_dirname: ('' + [pkg._dirname]) || null | ||
}; | ||
} | ||
} else if (filename) { | ||
return { | ||
name: 'node', | ||
version: nodeVersion | ||
}; | ||
} | ||
return null; | ||
} | ||
function originJSON(origin) { | ||
@@ -31,7 +64,16 @@ origin = '' + [origin]; | ||
return { | ||
var nestedOrigin = originJSON(matches[2]); | ||
var result = { | ||
invocation: invocation, | ||
name: name, | ||
origin: originJSON(matches[2]) | ||
origin: null | ||
}; | ||
if (nestedOrigin.invocation) { | ||
result.origin = nestedOrigin; | ||
} else { | ||
result = util._extend(result, nestedOrigin); | ||
} | ||
return result; | ||
} | ||
@@ -42,2 +84,3 @@ | ||
return { | ||
pkg: lookupPackage(matches[1]), | ||
filename: matches[1], | ||
@@ -100,2 +143,3 @@ line: matches[2] | 0, | ||
return { | ||
pkg: lookupPackage(filename), | ||
invocation: invocation, | ||
@@ -205,4 +249,146 @@ name: typeName, | ||
function formatJSONOrigin(origin) { | ||
var text = ''; | ||
if (origin.origin) { | ||
if (origin.origin.invocation) { | ||
text = origin.origin.invocation + ' at ' + | ||
(origin.origin.name || '<anonymous>'); | ||
} | ||
text += ' (' + formatJSONOrigin(origin.origin) + ')'; | ||
} | ||
if (origin.filename !== undefined) { | ||
if (text) { | ||
text += ', '; | ||
} | ||
var filename = '' + [origin.filename]; | ||
var pkg = origin.pkg; | ||
if (pkg && | ||
pkg._dirname && | ||
pkg._dirname.length < filename.length && | ||
filename.substring(0, pkg._dirname.length) === pkg._dirname) { | ||
filename = filename.substring(pkg._dirname.length); | ||
} | ||
if (pkg) { | ||
text += pkg.name + '@' + pkg.version + ' '; | ||
} | ||
text += filename || '<anonymous>'; | ||
if (origin.line) { | ||
text += ':' + origin.line; | ||
if (origin.column) { | ||
text += ':' + origin.column; | ||
} | ||
} | ||
} | ||
return text; | ||
} | ||
function formatJSONStack(frames, options) { | ||
return frames.map(function(frame) { | ||
var filename = frame.filename; | ||
var pkg = frame.pkg; | ||
if (pkg && | ||
pkg._dirname && | ||
pkg._dirname.length < filename.length && | ||
filename.substring(0, pkg._dirname.length) === pkg._dirname) { | ||
filename = filename.substring(pkg._dirname.length); | ||
} | ||
return ' at' + | ||
(frame.name ? (' ' + frame.name).yellow : '') + ' ' + | ||
((frame.name ? '(' : '') + | ||
formatJSONOrigin(frame) + | ||
(frame.name ? ')' : '')).grey; | ||
}).join('\n'); | ||
} | ||
function formatStack(error, options) { | ||
var isArray = Array.isArray(error); | ||
var data = util._extend(isArray ? [] : {}, error); | ||
var name; | ||
var message; | ||
var stack = ''; | ||
if (error instanceof Error) { | ||
delete data.name; | ||
delete data.message; | ||
name = error.name; | ||
message = error.message; | ||
if (options && Array.isArray(options.callSite)) { | ||
stack = options.callSite.map(frameJSON); | ||
} else { | ||
stack = error.toJSON().error_stack; | ||
} | ||
if (Array.isArray(stack)) { | ||
stack = formatJSONStack(stack, options); | ||
} else { | ||
stack = '' + [error.stack]; | ||
var stackFirstAt = stack.match(/\n.* +at +/); | ||
if (stackFirstAt) { | ||
stack = stack.substring(stackFirstAt.index + 1); | ||
} | ||
} | ||
} else if (typeof(error) === 'object') { | ||
if (error.error) { | ||
name = error.error; | ||
delete data.error; | ||
} else if (error.name) { | ||
name = error.name; | ||
delete data.name; | ||
} | ||
if (error.error_description) { | ||
message = error.error_description; | ||
delete data.error_description; | ||
} else if (error.message) { | ||
message = error.message; | ||
delete data.message; | ||
} | ||
name = name || (isArray ? 'Error array' : 'Error object'); | ||
if (isArray && data.length === 0) { | ||
data = null; | ||
} | ||
} else { | ||
name = 'Error value'; | ||
message = '' + error; | ||
data = null; | ||
} | ||
var cause = data ? data.cause : undefined; | ||
if (typeof(cause) === 'object') { | ||
delete data.cause; | ||
} else { | ||
cause = null; | ||
} | ||
name = ('' + [name]).trim() || 'Error object'; | ||
message = ('' + [message]).trim(); | ||
if (message) { | ||
name += ': '; | ||
} | ||
var text = name.cyan + (message ? message.bold : ''); | ||
if (data) { | ||
data = util.format(data); | ||
if (data !== '{}') { | ||
text += '\n' + data.replace(/^/mg, ' ').grey; | ||
} | ||
} | ||
if (stack) { | ||
text += '\n' + stack; | ||
} | ||
if (cause) { | ||
text += '\ncaused by ' + formatStack(cause, options); | ||
} | ||
return text; | ||
} | ||
var ferro = createError; | ||
ferro.getClass = getClass; | ||
ferro.stack = formatStack; | ||
module.exports = ferro; |
{ | ||
"name": "ferro", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Ferocious Error Handling", | ||
@@ -8,3 +8,6 @@ "repository": { | ||
"url": "http://github.com/walling/ferro.git" | ||
}, | ||
"dependencies": { | ||
"tinycolor": "0.0.1" | ||
} | ||
} |
12637
344
1
+ Addedtinycolor@0.0.1
+ Addedtinycolor@0.0.1(transitive)