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.2.7 to 0.2.8

lib/formatError.js

425

lib/trycatch.js

@@ -1,44 +0,24 @@

// Don't rely on domains to catch errors
// Use domains to pass caught errors to active
// Keep (add?) fix for event emitter handler
// emit uncaughtException if (isCore(err) && err instanceof EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError))
// when we run, set domain to active
// do usual long-stack-traces/trycatch run
//
// in guard, if it's eventemitter, reset active domain to closure domain
var util = require('util')
, domain = require('domain')
, path = require('path')
, formatter = require('./formatStackTrace')
, hookit = require('hookit')
, fileNameFilter = [__filename, require.resolve('hookit'), 'domain.js']
, node_modules = path.sep + 'node_modules' + path.sep
, originalFormatError = require('./formatError').formatError
, normalizeError = require('./formatError').normalizeError
, fileNameFilter = [__filename, require.resolve('hookit'), 'domain.js', 'Domain.emit']
, hasGuardedWithoutLST
, options
var delimitter = '----------------------------------------'
options = {
'long-stack-traces': null
, 'colors': {
'node': 'white',
'node_modules': 'cyan',
'default': 'red'
}
, 'format': defaultFormat
, 'filter': fileNameFilter
}
module.exports = trycatch
Error.stackTraceLimit = 30
// use colors module, if available
if (process.stdout.isTTY) {
try { trycatch.colors = require('colors') } catch(err) {}
'long-stack-traces': null
, 'colors': {
'node': 'white',
'node_modules': 'cyan',
'default': 'red'
}
, 'format': null
, 'filter': fileNameFilter
}
/* Run Logic */
function trycatch(tryFn, catchFn) {

@@ -51,132 +31,49 @@ if ('function' !== typeof tryFn || 'function' !== typeof catchFn) {

trycatch.run = run
trycatch.wrap = wrap
trycatch.configure = configure
trycatch.format = defaultFormat
hookit(function generateShim(callback, fnName) {
var newCallback = trycatch.wrap(callback, fnName)
newCallback.__proto__ = callback
return newCallback
})
function run(fn, cb) {
function run(tryFn, catchFn) {
var parentDomain = domain.active
, d = domain.create()
, stack
d.on('error', function(e) {
handleException(e, parentDomain, cb)
})
d.parentStack = parentDomain && parentDomain.currentStack
if (options['long-stack-traces']) {
fn = lstRunWrap(fn)
}
runInDomain(d, fn)
d.on('error', onError)
runInDomain(d, tryFn)
return d
}
function handleException(err, parentDomain, cb) {
var caught
err = formatError(err)
if (!err.catchable) {
// Unexpected error, core in undefined state, requires restart
caught = process.emit('uncaughtException', err)
// Otherwise crash the process
if (!caught) {
throw err
}
return
function onError(e) {
if (!e.caught) {
d.exit()
throw e
}
if (!parentDomain) {
if ('function' === typeof cb) {
cb(err)
return
if (e.rethrown) {
if (e.parentStack) {
e.stack += '\n ----------------------------------------\n' + e.parentStack
}
caught = process.emit('uncaughtApplicationException', err)
if (!caught) {
caught = process.emit('uncaughtException', err)
}
if (!caught) {
throw err
}
return
} else if (d.currentStack) {
e.stack += '\n ----------------------------------------\n' + d.currentStack
}
e = formatError(e)
runInDomain(parentDomain, function() {
cb(err)
})
}
function runInDomain(d, fn) {
if (!d || d._disposed) {
try {
fn()
} catch(e1) {
handleException(e1)
if(d.parentStack) {
e.parentStack = d.parentStack
}
return
}
try {
d.run(fn)
} catch(e2) {
d.emit('error', e2)
d.exit()
handleException(e, parentDomain, catchFn)
}
}
function isCatchableError(err) {
if (!isCoreError(err)) return true
/* Wrapping Logic */
// Unexpected runtime errors aren't catchable
if (err instanceof EvalError ||
err instanceof RangeError ||
err instanceof ReferenceError ||
err instanceof SyntaxError ||
err instanceof URIError) return false
// Can't catch invalid input errors more than 1 layer deep
return !isCoreSlice(err.stack.split('\n')[2])
}
function isCoreSlice(slice) {
return slice && slice.indexOf(path.sep) === -1
}
function isCoreError(err) {
return true !== err.coerced && isCoreSlice(err.stack.split('\n')[1])
}
function lstRunWrap(tryFn) {
// Create origin _TOKEN_ for stack termination
function _TOKEN_() {
tryFn()
}
_TOKEN_.error = new Error
_TOKEN_.origin = 'trycatch'
return _TOKEN_
}
// Generate a new callback wrapped in _TOKEN_ (optionally with Error for LSTs)
// Generate a new callback
// Ensure it runs in the same domain
function wrap(callback, name) {
var parentDomain = process.domain
var d = process.domain
, stack
if ('function' !== typeof callback) return callback
function _TOKEN_(that, args) {
callback.apply(that, args)
}
stack = getStack(d)
if (options['long-stack-traces']) {
_TOKEN_.origin = name
_TOKEN_.error = new Error
}
// Running in parentDomain should only be necessary for EventEmitter handlers
// Core should handle the rest
// Wrapping is still necessary to fix core error handling
return function() {

@@ -186,4 +83,5 @@ var that = this

runInDomain(parentDomain, function() {
_TOKEN_(that, args)
if (d) d.currentStack = stack
runInDomain(d, function() {
callback.apply(that, args)
})

@@ -193,195 +91,76 @@ }

function buildError(err, structuredStackTrace) {
var parent
, token
, isLST = options['long-stack-traces']
, skip = false
, isError = err instanceof Error
, stackToParent
function getStack(parentDomain) {
var stack = ''
// Coerce to error
if (!isError) {
err = new Error(err)
err.coerced = true
}
if (!isLST || !isError) {
if (!isError) console.warn('Unable to generate long-stack-trace for thrown non-Error')
if (structuredStackTrace) {
err.stack = formatter(err, structuredStackTrace)
} else {
err = generateStack(err)
if (options['long-stack-traces']) {
stack = new Error().stack.substr(6)
if (parentDomain && parentDomain.currentStack) {
stack += '\n ----------------------------------------\n' + parentDomain.currentStack
}
return setProperties(err)
}
// If previously caught
if (err.token) {
skip = true
token = err.token
} else {
if (structuredStackTrace) {
parent = stackSearch(err, structuredStackTrace)
} else {
parent = generateStack(err, stackSearch).stack
}
err.stack = formatStructuredStackTrace(err, parent.structuredStackTrace)
err = setProperties(err)
if (!parent.token) {
// options['long-stack-traces'] was probably toggled after async was invoked
return err
}
token = parent.token
parent = null
}
while(token.error) {
if (!skip && 'trycatch' === token.origin) break
skip = false
// HACK: Use Error.prepareStackTrace = stackSearch to find parent
parent = generateStack(token.error, stackSearch).stack
if (!parent || !parent.token) {
// An error occurred outside of trycatch
// Handle it by the usual means
return err
}
stackToParent = formatStructuredStackTrace(token.error, parent.structuredStackTrace, parent.token.error ? parent.index : undefined)
if ('trycatch' !== token.origin && stackToParent) {
err.stack += '\n ----------------------------------------\n' +
' at '+token.origin+'\n' +
stackToParent.substring(stackToParent.indexOf("\n") + 1)
}
token = parent.token
}
if ('trycatch' === token.origin) {
err.token = token
}
return err
return stack
}
function setProperties(err) {
err.coreThrown = isCoreError(err)
err.catchable = isCatchableError(err)
return err
}
Error.prepareStackTrace = prepareStackTrace
function prepareStackTrace(error, structuredStackTrace) {
var err = buildError(error, structuredStackTrace)
return err.stack = formatStack(err)
}
function generateStack(err, fn) {
var old = Error.prepareStackTrace
if ('function' !== typeof fn) {
fn = formatter
}
if (!err) err = new Error
Error.prepareStackTrace = fn
// Generate stack trace by accessing stack property
err.stack = err.stack
Error.prepareStackTrace = old
return err
}
function stackSearch(error, structuredStackTrace) {
var fn, i, l
if (!structuredStackTrace) return
for (i=0, l=structuredStackTrace.length; i<l; i++) {
fn = structuredStackTrace[i].fun
if ('_TOKEN_' === fn.name) {
return {
token: fn
, index: i
, structuredStackTrace: structuredStackTrace
}
function runInDomain(d, fn) {
if (!d || d._disposed) {
try {
fn()
} catch(e1) {
handleException(formatError(normalizeError(e1)))
}
return
}
return {
structuredStackTrace: structuredStackTrace
}
}
function formatStructuredStackTrace(error, structuredStackTrace, topIndex) {
var newStructuredStackTrace = []
, filter = false
, i, j, l, l2
topIndex = topIndex == null ? Infinity : topIndex
for (i=0, l=structuredStackTrace.length; i<l; i++) {
for(j=0, l2=options.filter.length; j<l2; j++) {
if (structuredStackTrace[i].getFileName().indexOf(options.filter[j]) !== -1) {
filter = true
continue
}
}
if (filter) {
filter = false
continue
}
newStructuredStackTrace.push(structuredStackTrace[i])
if (i>topIndex) break
try {
d.run(fn)
} catch(e2) {
d.emit('error', normalizeError(e2))
}
return formatter(error, newStructuredStackTrace)
}
/*
*/
function handleException(err, parentDomain, catchFn) {
var caught
function formatStack(err) {
var stack = err.stack.split('\n')
, newStack = []
, line
, i, l
for (i=0, l=stack.length; i<l; i++) {
line = trycatch.format(stack[i])
if (line) {
newStack.push(line)
if (!err.catchable) {
// Unexpected error, core in undefined state, requires restart
caught = process.emit('uncaughtException', err)
// Otherwise crash the process
if (!caught) {
throw err
}
return
}
return newStack.join('\n')
}
function defaultFormat(line) {
var type, color
if (trycatch.colors) {
if (line.indexOf(node_modules) >= 0) {
type = "node_modules";
} else if (line.indexOf(path.sep) >= 0) {
type = "default";
} else {
type = "node"
}
color = options.colors[type]
if ('none' === color || !Boolean(color)) {
if (!parentDomain) {
if ('function' === typeof catchFn) {
catchFn(err)
return
}
if (trycatch.colors[color]) {
return trycatch.colors[color](line);
caught = process.emit('uncaughtApplicationException', err)
if (!caught) {
caught = process.emit('uncaughtException', err)
}
if (!caught) {
throw err
}
return
}
return line
runInDomain(parentDomain, function() {
catchFn(err)
})
}
function formatError(err) {
err = buildError(err)
err.stack = formatStack(err)
return err
return originalFormatError(err
, {
'long-stack-traces': options['long-stack-traces']
, lineFormatter: trycatch.format
, colors: options.colors
, filter: options.filter
})
}
/* Config Logic */
function configure(opts) {

@@ -395,6 +174,6 @@ if (null != opts['long-stack-traces']) {

}
// findToken fails when _TOKEN_ deeper than Error.stackTraceLimit
// No longer necessary, but nice to have
Error.stackTraceLimit = Infinity
} else {
Error.stackTraceLimit = 30
Error.stackTraceLimit = 10
}

@@ -420,3 +199,3 @@ options['long-stack-traces'] = opts['long-stack-traces']

} else if (!Boolean(opts.format)) {
trycatch.format = options.format = defaultFormat
trycatch.format = null
}

@@ -430,1 +209,19 @@ }

/* Setup Logic */
// Pass callback wrapping function to hookit
hookit(function generateShim(callback, fnName) {
if ('function' !== typeof callback) return callback
var newCallback = trycatch.wrap(callback, fnName)
// Inherit from callback for when properties are added
if (newCallback !== callback) newCallback.__proto__ = callback
return newCallback
})
trycatch.run = run
trycatch.wrap = wrap
trycatch.configure = configure
trycatch.format = null
module.exports = trycatch
{
"name": "trycatch",
"version": "0.2.7",
"version": "0.2.8",
"description": "An asynchronous domain-based exception handler with long stack traces for node.js",

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

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