New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

trycatch

Package Overview
Dependencies
Maintainers
1
Versions
75
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

trycatch - npm Package Compare versions

Comparing version

to
0.2.1

examples/colors.js

163

lib/formatStackTrace.js

@@ -27,106 +27,101 @@ // Copyright 2006-2008 the V8 project authors. All rights reserved.

// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
module.exports = FormatStackTrace;
module.exports = function(format, filter) {
filter = Array.isArray(filter) ? filter : []
var path = require('path'),
d = path.join('/'),
node_modules = d + 'node_modules' + d;
function FormatStackTrace(error, frames, filter, colors) {
var lines = [];
try {
lines.push(error.toString());
} catch (e) {
function FormatStackTrace(error, frames) {
var lines = [];
try {
lines.push("<error: " + e + ">");
} catch (ee) {
lines.push("<error>");
}
}
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
var line;
try {
line = FormatSourcePosition(frame, filter);
lines.push(error.toString());
} catch (e) {
try {
line = "<error: " + e + ">";
lines.push("<error: " + e + ">");
} catch (ee) {
// Any code that reaches this point is seriously nasty!
line = "<error>";
lines.push("<error>");
}
}
if (line !== undefined) {
line = " at " + line;
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
var line;
try {
line = FormatSourcePosition(frame);
} catch (e) {
try {
line = "<error: " + e + ">";
} catch (ee) {
// Any code that reaches this point is seriously nasty!
line = "<error>";
}
}
if (line !== undefined) {
line = " at " + line;
if (colors) {
if (line.indexOf(node_modules) >= 0) {
line = colors.cyan(line);
} else if (line.indexOf(d) >= 0) {
line = colors.red(line);
} else {
line = colors.white(line);
if ('function' === typeof format) {
line = format(line)
}
if (line) {
lines.push(line);
}
}
lines.push(line);
}
return lines.join("\n");
}
return lines.join("\n");
}
function FormatSourcePosition(frame, filter) {
var fileLocation = "";
if (frame.isNative()) {
fileLocation = "native";
} else if (frame.isEval()) {
fileLocation = "eval at " + frame.getEvalOrigin();
} else {
var fileName = frame.getFileName();
if (fileName) {
for(var i=0, l=filter.length; i<l; i++) {
if (fileName.indexOf(filter[i]) !== -1) return;
function FormatSourcePosition(frame) {
var fileLocation = "";
if (frame.isNative()) {
fileLocation = "native";
} else if (frame.isEval()) {
fileLocation = "eval at " + frame.getEvalOrigin();
} else {
var fileName = frame.getFileName();
if (fileName) {
for(var i=0, l=filter.length; i<l; i++) {
if (fileName.indexOf(filter[i]) !== -1) return;
}
fileLocation += fileName;
var lineNumber = frame.getLineNumber();
if (lineNumber != null) {
fileLocation += ":" + lineNumber;
var columnNumber = frame.getColumnNumber();
if (columnNumber) {
fileLocation += ":" + columnNumber;
}
}
}
fileLocation += fileName;
var lineNumber = frame.getLineNumber();
if (lineNumber != null) {
fileLocation += ":" + lineNumber;
var columnNumber = frame.getColumnNumber();
if (columnNumber) {
fileLocation += ":" + columnNumber;
}
if (!fileLocation) {
fileLocation = "unknown source";
}
var line = "";
var functionName = frame.getFunction().name;
var addPrefix = true;
var isConstructor = frame.isConstructor();
var isMethodCall = !(frame.isToplevel() || isConstructor);
if (isMethodCall) {
var methodName = frame.getMethodName();
line += frame.getTypeName() + ".";
if (functionName) {
line += functionName;
if (methodName && (methodName != functionName)) {
line += " [as " + methodName + "]";
}
} else {
line += methodName || "<anonymous>";
}
}
}
if (!fileLocation) {
fileLocation = "unknown source";
}
var line = "";
var functionName = frame.getFunction().name;
var addPrefix = true;
var isConstructor = frame.isConstructor();
var isMethodCall = !(frame.isToplevel() || isConstructor);
if (isMethodCall) {
var methodName = frame.getMethodName();
line += frame.getTypeName() + ".";
if (functionName) {
} else if (isConstructor) {
line += "new " + (functionName || "<anonymous>");
} else if (functionName) {
line += functionName;
if (methodName && (methodName != functionName)) {
line += " [as " + methodName + "]";
}
} else {
line += methodName || "<anonymous>";
line += fileLocation;
addPrefix = false;
}
} else if (isConstructor) {
line += "new " + (functionName || "<anonymous>");
} else if (functionName) {
line += functionName;
} else {
line += fileLocation;
addPrefix = false;
if (addPrefix) {
line += " (" + fileLocation + ")";
}
return line;
}
if (addPrefix) {
line += " (" + fileLocation + ")";
}
return line;
return FormatStackTrace
}

@@ -7,8 +7,19 @@ var util = require('util')

, fileNameFilter = [__filename, require.resolve('./hook'), 'domain.js']
, d = require('path').join('/')
, node_modules = d + 'node_modules' + d
, options = {
'long-stack-traces': null
, 'colors': {
'node': 'white',
'node_modules': 'cyan',
'default': 'red'
}
, 'format': defaultFormat
, 'filter': fileNameFilter
}
// use colors module, if available
try { trycatch.colors = require('colors') } catch(err) {}
if (process.stdout.isTTY) {
try { trycatch.colors = require('colors') } catch(err) {}
}

@@ -28,26 +39,60 @@ module.exports = trycatch

trycatch.configure = configure
trycatch.format = FormatStackTrace(defaultFormat, fileNameFilter)
function configure(opts) {
var resetFormat = false
if ('undefined' !== typeof opts['long-stack-traces']) {
options['long-stack-traces'] = Boolean(opts['long-stack-traces'])
if (true === options['long-stack-traces']) {
if (!hooked) {
hooked = true
// Replace built-in async functions, shim callbacks with generator
hookit()
}
// findToken fails when _TOKEN_ deeper than Error.stackTraceLimit
Error.stackTraceLimit = Infinity
trycatch.begin = longStackTraceBegin
trycatch.guard = longStackTraceGuard
} else if (false === options['long-stack-traces'] && hooked) {
console.warn('Turning long-stack-traces off can result in indeterminate behavior.')
Error.stackTraceLimit = 10
trycatch.begin = domainTrycatch
trycatch.guard = nopGuard
}
}
if (true === options['long-stack-traces']) {
if (!hooked) {
hooked = true
// Replace built-in async functions, shim callbacks with generator
hookit()
if (null != opts.colors && 'object' === typeof opts.colors) {
if ('undefined' !== typeof opts.colors.node) {
options.colors.node = opts.colors.node
}
if ('undefined' !== typeof opts.colors.node_modules) {
options.colors.node_modules = opts.colors.node_modules
}
if ('undefined' !== typeof opts.colors.default) {
options.colors.default = opts.colors.default
}
}
// findToken fails when _TOKEN_ deeper than Error.stackTraceLimit
Error.stackTraceLimit = Infinity
trycatch.begin = longStackTraceBegin
trycatch.guard = longStackTraceGuard
} else if (false === options['long-stack-traces'] && hooked) {
console.warn('Turning long-stack-traces off can result in indeterminate behavior.')
Error.stackTraceLimit = 10
trycatch.begin = domainTrycatch
trycatch.guard = nopGuard
if ('undefined' !== typeof opts.format) {
if ('function' === typeof opts.format) {
options.format = opts.format
resetFormat = true
} else if (!Boolean(opts.format)) {
options.format = defaultFormat
resetFormat = true
}
}
if (Array.isArray(opts.filter)) {
options.filter = opts.filter
resetFormat = true
}
if (resetFormat) {
trycatch.format = FormatStackTrace(options.format, options.filter)
}
}

@@ -57,3 +102,3 @@

hook(function generateShim(callback, fnName) {
return trycatch.guard(callback, fnName)
return trycatch.guard(callback, fnName)
})

@@ -67,45 +112,47 @@ }

function domainTrycatch (fn, cb, token) {
var parentDomain = domain.active
, d = domain.create()
function domainTrycatch (fn, cb, isLongStackTrace) {
var parentDomain = domain.active
, d = domain.create()
d.on('error', function onError(err) {
var isError = err instanceof Error
if (true === options['long-stack-traces'] && '_TOKEN_' === fn.name) {
if (isError) {
err = handleError(err)
} else {
console.warn('Unable to generate long-stack-trace for thrown non-Error')
}
}
d.on('error', function onError(err) {
err = buildError(err, Boolean(options['long-stack-traces'] && isLongStackTrace))
if (!isError) {
err = new Error(err)
}
runInDomain(parentDomain, function() {
cb(err)
})
})
runInDomain(d, fn)
runInDomain(parentDomain, function() {
cb(err)
})
})
runInDomain(d, fn)
}
function runInDomain(d, fn) {
if (d && !d._disposed) {
try {
d.run(fn)
} catch(e) {
d.emit('error', e)
}
} else {
fn()
}
if (d && !d._disposed) {
try {
d.run(fn)
} catch(e) {
d.emit('error', e)
}
} else {
fn()
}
}
function handleError(err) {
function buildError(err, isLongStackTrace) {
var parent
, token
, skip = false
, isError = err instanceof Error
// Coerce to error
if (!isError) {
err = new Error(err)
}
if (!isLongStackTrace) {
return generateStack(err)
} else if (!isError) {
console.warn('Unable to generate long-stack-trace for thrown non-Error')
return generateStack(err)
}
if (err.token) {

@@ -159,3 +206,3 @@ skip = true

domainTrycatch(_TOKEN_, catchFn)
domainTrycatch(_TOKEN_, catchFn, true)
}

@@ -165,8 +212,3 @@

if ('function' !== typeof fn) {
fn = function(error, structuredStackTrace) {
return FormatStackTrace(error
, structuredStackTrace
, fileNameFilter
, trycatch.colors)
}
fn = trycatch.format
}

@@ -207,9 +249,9 @@ if (!err) err = new Error

function stackSearch(error, structuredStackTrace) {
var stack
var stack, fn, i, l
if (!structuredStackTrace) return
stack = FormatStackTrace(error, structuredStackTrace, fileNameFilter, trycatch.colors)
stack = trycatch.format(error, structuredStackTrace)
for (var fn, i=0, l=structuredStackTrace.length; i<l; i++) {
for (i=0, l=structuredStackTrace.length; i<l; i++) {
fn = structuredStackTrace[i].fun

@@ -224,2 +266,26 @@ if ('_TOKEN_' === fn.name) {

return {stack: stack}
}
}
function defaultFormat(line) {
var type, color
if (trycatch.colors) {
if (line.indexOf(node_modules) >= 0) {
type = "node_modules";
} else if (line.indexOf(d) >= 0) {
type = "default";
} else {
type = "node"
}
color = options.colors[type]
if ('none' === color || !Boolean(color)) {
return
}
if (trycatch.colors[color]) {
return trycatch.colors[color](line);
}
}
return line
}
{
"name": "trycatch",
"version": "0.2.0",
"version": "0.2.1",
"description": "An asynchronous domain-based exception handler with long stack traces for node.js",

@@ -5,0 +5,0 @@ "homepage": "http://github.com/CrabDude/trycatch",

trycatch
=======
An asynchronous try catch exception handler with long stack traces for node.js
An asynchronous domain-based try/catch exception handler with (optional) long stack traces for node.js
**Now PRODUCTION Ready!**
With the update to 0.2.0
* error-handling is now [domain-based](http://nodejs.org/api/domain.html)
* long-stack-traces are optional (off by default)
* long-stack-traces are lazy
With the update to 0.1.0, stack traces are now lazy, and all try/catch blocks conform to [V8 best practices](https://github.com/joyent/node/wiki/Best-practices-and-gotchas-with-v8).
Also, trycatch conforms to try/catch [V8 best practices](https://github.com/joyent/node/wiki/Best-practices-and-gotchas-with-v8).

@@ -20,7 +23,42 @@

Because trycatch shims all native I/O calls, it must be required before any other modules.
```javascript
var trycatch = require('trycatch')
trycatch(fnTry, fnCatch)
```
var trycatch = require('trycatch')
trycatch(fnTry, fnCatch)
Optional Long-Stack-Traces:
```javascript
// Because trycatch shims all native I/O calls,
// it must be required & configured with 'long-stack-traces' before any other modules.
var trycatch = require('trycatch')
trycatch.configure({'long-stack-traces': true})
trycatch(fnTry, fnCatch)
```
Colors:
```javascript
var trycatch = require('trycatch')
trycatch.configure({
colors: {
// 'none' or falsy values will omit
'node': 'none',
'node_modules': false,
'default': 'yellow'
}
})
trycatch(fnTry, fnCatch)
```
Advanced Formatting:
```javascript
var trycatch = require('trycatch')
trycatch.configure({
format: function(line) {
// Alter final output (falsy values will omit)
return line
}
})
trycatch(fnTry, fnCatch)
```
Basic Example

@@ -30,15 +68,14 @@ -------------

```javascript
var trycatch = require("trycatch"),
_ = require('underscore')._
var trycatch = require("trycatch"),
_ = require('underscore')._
trycatch(function() {
_.map(['Error 1', 'Error 2'], function foo(v) {
setTimeout(function() {
throw new Error(v)
}, 10)
})
}, function(err) {
console.log("Async error caught!\n", err.stack);
});
trycatch(function() {
_.map(['Error 1', 'Error 2'], function foo(v) {
setTimeout(function() {
throw new Error(v)
}, 10)
})
}, function(err) {
console.log("Async error caught!\n", err.stack);
});
```

@@ -60,12 +97,12 @@

```javascript
http.createServer(function(req, res) {
trycatch(function() {
setTimeout(function() {
throw new Error('Baloney!');
}, 1000);
}, function(err) {
res.writeHead(500);
res.end(err.stack);
});
}).listen(8000);
http.createServer(function(req, res) {
trycatch(function() {
setTimeout(function() {
throw new Error('Baloney!');
}, 1000);
}, function(err) {
res.writeHead(500);
res.end(err.stack);
});
}).listen(8000);
```

@@ -80,2 +117,2 @@

Special thanks to [Tom Robinson](https://github.com/tlrobinson) for his [long-stack-traces](https://github.com/tlrobinson/long-stack-traces) module and [Tim Caswell](https://github.com/creationix) who built out the initial hook.js code.
Special thanks to [Tom Robinson](https://github.com/tlrobinson) for his [long-stack-traces](https://github.com/tlrobinson/long-stack-traces) module and [Tim Caswell](https://github.com/creationix) who built out the initial hook.js code.

@@ -21,3 +21,3 @@ var trycatch = require('../lib/trycatch')

assert.throws(function() {
trycatch(null, function() {})
trycatch(null, function() {})
}, Error)

@@ -24,0 +24,0 @@ })