Huge News!Announcing our $40M Series B led by Abstract Ventures.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 0.0.11 to 0.1.0

examples/underscore.js

28

lib/formatStackTrace.js

@@ -28,3 +28,8 @@ // Copyright 2006-2008 the V8 project authors. All rights reserved.

module.exports = FormatStackTrace;
function FormatStackTrace(error, frames) {
var path = require('path'),
d = path.join('/'),
node_modules = d + 'node_modules' + d;
function FormatStackTrace(error, frames, filter, colors) {
var lines = [];

@@ -44,3 +49,3 @@ try {

try {
line = FormatSourcePosition(frame);
line = FormatSourcePosition(frame, filter);
} catch (e) {

@@ -54,3 +59,15 @@ try {

}
lines.push(" at " + line);
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);
}
}
lines.push(line);
}
}

@@ -60,3 +77,3 @@ return lines.join("\n");

function FormatSourcePosition(frame) {
function FormatSourcePosition(frame, filter) {
var fileLocation = "";

@@ -70,2 +87,5 @@ if (frame.isNative()) {

if (fileName) {
for(var i=0, l=filter.length; i<l; i++) {
if (fileName.indexOf(filter[i]) !== -1) return;
}
fileLocation += fileName;

@@ -72,0 +92,0 @@ var lineNumber = frame.getLineNumber();

64

lib/hook.js

@@ -6,57 +6,57 @@ /**

module.exports = function hook(wrap) {
if (alreadyRequired) throw new Error("This should only be required and used once");
alreadyRequired = true;
if (alreadyRequired) throw new Error("This should only be required and used once")
alreadyRequired = true
// Wrap setTimeout and setInterval
["setTimeout", "setInterval"].forEach(function (name) {
var original = this[name];
;["setTimeout", "setInterval"].forEach(function (name) {
var original = this[name]
this[name] = function (callback) {
arguments[0] = wrap(callback, name);
return original.apply(this, arguments);
};
});
arguments[0] = wrap(callback, name)
return original.apply(this, arguments)
}
})
// Wrap process.nextTick
var nextTick = process.nextTick;
var nextTick = process.nextTick
process.nextTick = function wrappedNextTick(callback) {
arguments[0] = wrap(callback, 'process.nextTick');
return nextTick.apply(this, arguments);
};
arguments[0] = wrap(callback, 'process.nextTick')
return nextTick.apply(this, arguments)
}
// Wrap FS module async functions
var FS = require('fs');
var FS = require('fs')
Object.keys(FS).forEach(function (name) {
// If it has a *Sync counterpart, it's probably async
if (!FS.hasOwnProperty(name + "Sync")) return;
var original = FS[name];
if (!FS.hasOwnProperty(name + "Sync")) return
var original = FS[name]
FS[name] = function () {
var i = arguments.length - 1;
var i = arguments.length - 1
if (typeof arguments[i] === 'function') {
arguments[i] = wrap(arguments[i], 'fs.'+name);
arguments[i] = wrap(arguments[i], 'fs.'+name)
}
return original.apply(this, arguments);
};
});
return original.apply(this, arguments)
}
})
// Wrap EventEmitters
var EventEmitter = require('events').EventEmitter;
var onEvent = EventEmitter.prototype.on;
var EventEmitter = require('events').EventEmitter
var onEvent = EventEmitter.prototype.on
EventEmitter.prototype.on = EventEmitter.prototype.addListener = function (type, callback) {
var newCallback = wrap(callback, 'EventEmitter.on');
var newCallback = wrap(callback, 'EventEmitter.on')
if (newCallback !== callback) {
callback.wrappedCallback = newCallback;
arguments[1] = newCallback;
callback.wrappedCallback = newCallback
arguments[1] = newCallback
}
return onEvent.apply(this, arguments);
};
var removeEvent = EventEmitter.prototype.removeListener;
return onEvent.apply(this, arguments)
}
var removeEvent = EventEmitter.prototype.removeListener
EventEmitter.prototype.removeListener = function (type, callback) {
if (callback && callback.hasOwnProperty("wrappedCallback")) {
arguments[1] = callback.wrappedCallback;
arguments[1] = callback.wrappedCallback
}
return removeEvent.apply(this, arguments);
};
return removeEvent.apply(this, arguments)
}
}
var alreadyRequired;
var alreadyRequired

@@ -1,94 +0,111 @@

module.exports = trycatch;
module.exports = trycatch
// use colors module, if available
try { trycatch.colors = require('colors'); } catch(err) {}
var FormatStackTrace = require('./formatStackTrace');
var path = require('path');
var d = path.join('/');
try { trycatch.colors = require('colors') } catch(err) {}
var FormatStackTrace = require('./formatStackTrace'),
filename1 = __filename,
filename2 = require.resolve('./hook')
// findToken fails when _TOKEN_ deeper than Error.stackTraceLimit
Error.stackTraceLimit = Infinity
// findToken fails for stack traces deeper Error.stackTraceLimit => Error.stackTraceLimit = Infinity
// Make configurable?
Error.stackTraceLimit = Infinity;
// The event-source hooks allows tokens & new stacks to be linked
// called as shim
require('./hook')(generateShim);
// Replace built-in async functions, shim callbacks
require('./hook')(generateShim)
// generate a new callback shim for shim'd async function (e.g., fs.stats)
// Generate a new callback wrapped in _TOKEN_ with Error to trace back
function generateShim(next, name, location) {
var self;
var res = findToken();
if (!res) return next;
var token = res.token;
var stack = res.stack;
// _TOKEN_ is the new callback and calls the real callback, next()
if (typeof next !== 'function') return next
// _TOKEN_ is the new callback and calls the real callback, next()
function _TOKEN_() {
try {
return next.apply(self, arguments);
} catch (err) {
if (!(err instanceof Error)) {
err = new Error(''+err);
}
var catchFn;
token = _TOKEN_;
err.stack = filterInternalFrames(err.stack);
while(token.token) {
if (token.stack) {
err.stack += '\n ----------------------------------------\n' +
' at '+token.orig+'\n' +
token.stack.substring(token.stack.indexOf("\n") + 1)
}
catchFn = token = token.token;
}
catchFn(err);
return next.apply(this, arguments)
} catch (e) {
handleError(e, _TOKEN_, false)
}
}
_TOKEN_.orig = name;
_TOKEN_.stack = stack;
_TOKEN_.token = token;
_TOKEN_.orig = name
_TOKEN_.error = new Error
return function() {
self = this;
_TOKEN_.apply(token, arguments);
};
return _TOKEN_
}
// Tags a stack and all decendent stacks with a token
function handleError(err, token, recursive) {
var origin
if (!recursive) {
if (!err.token) {
// Newly created Error
err = err instanceof Error ? err : new Error(''+err)
err = getFilteredError(err)
err.originalStack = err.stack
} else {
token = err.token
}
}
while(token.error) {
// stackSearch returns an object {token, stack} in place of error.stack String
origin = getFilteredError(token.error, stackSearch).stack
if (!origin) throw err
if (!token.catchFn && origin.stack) {
err.stack += '\n ----------------------------------------\n' +
' at '+token.orig+'\n' +
origin.stack.substring(origin.stack.indexOf("\n") + 1)
}
token = origin.token
if (token.catchFn) break
}
if (typeof token.catchFn === 'function') {
err.token = token
try {
token.catchFn.call(null, err, token)
} catch(e2) {
handleError(e2, token, true)
}
}
}
// Create origin _TOKEN_ for stack termination
function trycatch(tryFn, catchFn) {
function _TOKEN_() {
tryFn();
tryFn()
}
_TOKEN_.token = catchFn;
_TOKEN_.catchFn = catchFn
_TOKEN_.error = new Error
_TOKEN_.orig = 'trycatch'
try {
_TOKEN_();
_TOKEN_()
} catch (err) {
err.stack = filterInternalFrames(err.stack);
catchFn(err);
catchFn(getFilteredError(err))
}
}
// Looks for a token in the current stack using the V8 stack trace API
function findToken(err) {
if (!err) err = new Error();
var original = Error.prepareStackTrace;
// stackSearch returns a function object instead of the string expected from the built-in
Error.prepareStackTrace = stackSearch;
var res = err.stack;
Error.prepareStackTrace = original;
err.stack = res && res.stack;
return res;
function getFilteredError(err, fn) {
if (typeof fn !== 'function') {
fn = function(error, structuredStackTrace) {
return FormatStackTrace(error, structuredStackTrace, [filename1, filename2], trycatch.colors)
}
}
if (!err) err = new Error;
var old = Error.prepareStackTrace
Error.prepareStackTrace = fn
err.stack = err.stack
Error.prepareStackTrace = old
return err
}
function stackSearch(error, structuredStackTrace) {
if (!structuredStackTrace) return;
if (!structuredStackTrace) return
for (var fn, i = 0, l = structuredStackTrace.length; i < l; i++) {
fn = structuredStackTrace[i].fun;
for (var fn, i=0, l=structuredStackTrace.length; i<l; i++) {
fn = structuredStackTrace[i].fun
if (fn.name === '_TOKEN_') {
return {
token: fn,
stack: filterInternalFrames(FormatStackTrace(error, structuredStackTrace))
stack: FormatStackTrace(error, structuredStackTrace, [filename1, filename2], trycatch.colors)
}

@@ -98,21 +115,1 @@ }

}
var filename1 = __filename;
var filename2 = require.resolve('./hook');
function filterInternalFrames(frames) {
var ret = [];
ret = frames.split("\n").filter(function(frame) {
return frame.indexOf(filename1) < 0 && frame.indexOf(filename2) < 0;
});
if (trycatch.colors) {
ret = ret.map(function(frame, k) {
if (frame.indexOf(d + 'node_modules' + d) >= 0) {
frame = trycatch.colors.cyan(frame);
} else if (frame.indexOf(d) >= 0) {
frame = trycatch.colors.red(frame);
}
return frame;
});
}
return ret.join("\n");
}
{
"name" : "trycatch",
"version" : "0.0.11",
"description" : "An asynchronous exception handler with long stack traces for node.js",
"homepage": "http://github.com/CrabDude/trycatch",
"repository": {
"type" : "git",
"url" : "git://github.com/CrabDude/trycatch.git"
},
"bugs" : { "web" : "http://github.com/CrabDude/trycatch/issues" },
"author" : "Adam Crabtree <dude@noderiety.com> (http://noderiety.com)",
"main" : "lib/trycatch",
"directories" : { "lib" : "./lib/" },
"engines" : { "node" : ">=0.2.0" },
"licenses" : [{
"type" : "MIT",
"url" : "http://www.opensource.org/licenses/mit-license.html"
}],
"dependencies" : {
"colors": ">=0.5.0 <0.6"
},
"keywords": [
"error",
"exception",
"try",
"catch",
"stack",
"trace"
]
"name": "trycatch",
"version": "0.1.0",
"description": "An asynchronous exception handler with long stack traces for node.js",
"homepage": "http://github.com/CrabDude/trycatch",
"repository": {
"type": "git",
"url": "git://github.com/CrabDude/trycatch.git"
},
"bugs": {
"url": "http://github.com/CrabDude/trycatch/issues"
},
"author": "Adam Crabtree <dude@noderiety.com> (http://noderiety.com)",
"main": "lib/trycatch",
"directories": {
"lib": "./lib/"
},
"engines": {
"node": ">=0.2.0"
},
"scripts": {
"test": "mocha --reporter spec ./test/*.js"
},
"licenses": [
{
"type": "MIT",
"url": "http://www.opensource.org/licenses/mit-license.html"
}
],
"dependencies": {
"colors": ">=0.5.0 <0.6"
},
"keywords": [
"error",
"exception",
"try",
"catch",
"stack",
"trace"
],
"devDependencies": {
"mocha": "~1.4.0",
"underscore": "~1.3.3"
}
}
trycatch
=======
An asynchronous try catch / exception handler with long stack traces for node.js
An asynchronous try catch exception handler with long stack traces for node.js
Background
----------
**Now PRODUCTION Ready!**
See the "Background" from the [long-stack-traces](https://github.com/tlrobinson/long-stack-traces) module.
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).
Install

@@ -16,46 +17,43 @@ -------

Use
---
Because trycatch shims all native I/O calls, it must be required before any other modules.
var trycatch = require('trycatch')
trycatch(fnTry, fnCatch)
Basic Example
-------------
trycatch(function() {
function f() {
throw new Error('foo');
}
setTimeout(f, Math.random()*1000);
setTimeout(f, Math.random()*1000);
}, function(err) {
console.log("This is an asynchronous scoped error handler!\n", err.stack);
});
```javascript
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);
});
```
#### Output
$ node examples/setTimeout.js
This is an asynchronous scoped error handler!
Error: foo
at Object.f (/path/to/trycatch/examples/setTimeout.js:5:9)
at Timer.callback (timers.js:83:39)
----------------------------------------
at setTimeout
at /path/to/trycatch/examples/setTimeout.js:8:2
at Object.<anonymous> (/path/to/trycatch/examples/setTimeout.js:3:1)
at Module._compile (module.js:404:26)
at Object..js (module.js:410:10)
at Module.load (module.js:336:31)
This is an asynchronous scoped error handler!
Error: foo
at Object.f (/path/to/trycatch/examples/setTimeout.js:5:9)
at Timer.callback (timers.js:83:39)
----------------------------------------
at setTimeout
at /path/to/trycatch/examples/setTimeout.js:9:2
at Object.<anonymous> (/path/to/trycatch/examples/setTimeout.js:3:1)
at Module._compile (module.js:404:26)
at Object..js (module.js:410:10)
at Module.load (module.js:336:31)
![](https://raw.github.com/CrabDude/trycatch/master/screenshot.png)
Advanced Examples
-------------
See the `/test` and `examples` directories for more use cases.
Returning 500s on Server Request
--------------------------------
```javascript
http.createServer(function(req, res) {

@@ -71,3 +69,11 @@ trycatch(function() {

}).listen(8000);
```
Visit http://localhost:8000 and get your 500.
Visit http://localhost:8000 and get your 500.
Thanks
----------
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.

@@ -1,6 +0,4 @@

'use strict';
var assert = require('assert'),
trycatch = require('../lib/trycatch')
var assert = require('assert');
var trycatch = require('../lib/trycatch');
/*

@@ -14,77 +12,42 @@ This test is to test whether trycatch can handle non-Errors being thrown

TypeError: Cannot call method 'split' of undefined
*/
describe('non-Errors', function() {
it('should catch Strings', function (done) {
trycatch(function () {
setTimeout(function () {
throw 'my-string being thrown'
}, 0)
}, function onError(err) {
assert.equal(err.message, 'my-string being thrown')
assert.notEqual(err.stack, undefined)
done()
})
})
To run this test: node ./throw-string.test.js
*/
it('should catch Numbers', function (done) {
trycatch(function () {
setTimeout(function () {
throw 123
}, 0)
}, function onError(err) {
assert.equal(err.message, (123).toString())
assert.notEqual(err.stack, undefined)
done()
})
})
//be compatible with running test from command line or from something like Expresso
var EXIT = (require.main === module) ? 'exit' : 'beforeExit';
it('should catch Booleans', function (done) {
var onErrorCalled = false
exports['throwing non-Error object like string should be caught'] = function () {
var onErrorCalled = false;
trycatch(function () {
setTimeout(function () {
throw 'my-string being thrown'; //throwing a string non-Error object
}, 100);
}, function onError(err) {
onErrorCalled = true;
assert.equal(err.message, 'my-string being thrown');
assert.notEqual(err.stack, undefined);
});
process.on(EXIT, function () {
//check callbacks were called here
assert.equal(onErrorCalled, true, 'throw string onError function should have been called');
console.error('success - caught thrown String');
});
};
exports['throwing non-Error object like number should be caught'] = function () {
var onErrorCalled = false;
trycatch(function () {
setTimeout(function () {
throw 123; //throwing a number non-Error object
}, 100);
}, function onError(err) {
onErrorCalled = true;
assert.equal(err.message, (123).toString());
assert.notEqual(err.stack, undefined);
});
process.on(EXIT, function () {
//check callbacks were called here
assert.equal(onErrorCalled, true, 'throw number onError function should have been called');
console.error('success - caught thrown number');
});
};
exports['throwing non-Error object like boolean should be caught'] = function () {
var onErrorCalled = false;
trycatch(function () {
setTimeout(function () {
throw true; //throwing a boolean non-Error object
}, 100);
}, function onError(err) {
onErrorCalled = true;
assert.equal(err.message, (true).toString());
assert.notEqual(err.stack, undefined);
});
process.on(EXIT, function () {
//check callbacks were called here
assert.equal(onErrorCalled, true, 'throw boolean onError function should have been called');
console.error('success - caught thrown boolean');
});
};
// if run directly from node execute all the exports
if (require.main === module) Object.keys(exports).forEach(function (f) { exports[f](); });
trycatch(function () {
setTimeout(function () {
throw true
}, 0)
}, function onError(err) {
assert.equal(err.message, (true).toString())
assert.notEqual(err.stack, undefined)
done()
})
})
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc