Comparing version 2.1.2 to 2.2.0
@@ -0,1 +1,11 @@ | ||
# 2.2.0 - 10/02/2017 | ||
- Fixed all Node v8 tests to ensure everything is working correctly [See #366] | ||
- Raven now uses Prettier to format it's code [See #364] | ||
- Prevent Raven from queueing too many requests in case server is down [See #132] | ||
- Enable keep-alive on socket connection and limit number of sockets [See #284] | ||
- Pull Error's name from constructor, not Error itself to always get correct error type [See #372] | ||
- Updated Errors serialization to store all additional properties and allow for attaching other object instances directly to it [See #376] | ||
- Preserve some non-enumerable properties from request [See #379] | ||
- Fall back to NODE_ENV for Sentry Environment [See #384] | ||
# 2.1.2 - 8/16/2017 | ||
@@ -2,0 +12,0 @@ - Remove errant large file that accidentally got published in 2.1.1. [See #361] |
'use strict'; | ||
var stringify = require('json-stringify-safe'); | ||
var stringify = require('../vendor/json-stringify-safe'); | ||
var parsers = require('./parsers'); | ||
@@ -28,4 +28,10 @@ var zlib = require('zlib'); | ||
// We get lots of users using raven-node when they want raven-js, hence this warning if it seems like a browser | ||
if (typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined') { | ||
utils.consoleAlertOnce('This looks like a browser environment; are you sure you don\'t want Raven.js for browser JavaScript? https://sentry.io/for/javascript'); | ||
if ( | ||
typeof window !== 'undefined' && | ||
typeof document !== 'undefined' && | ||
typeof navigator !== 'undefined' | ||
) { | ||
utils.consoleAlertOnce( | ||
"This looks like a browser environment; are you sure you don't want Raven.js for browser JavaScript? https://sentry.io/for/javascript" | ||
); | ||
} | ||
@@ -52,3 +58,4 @@ | ||
this.release = options.release || process.env.SENTRY_RELEASE || ''; | ||
this.environment = options.environment || process.env.SENTRY_ENVIRONMENT || ''; | ||
this.environment = | ||
options.environment || process.env.SENTRY_ENVIRONMENT || process.env.NODE_ENV || ''; | ||
@@ -66,2 +73,3 @@ // autoBreadcrumbs: true enables all, autoBreadcrumbs: false disables all | ||
this.sampleRate = typeof options.sampleRate === 'undefined' ? 1 : options.sampleRate; | ||
this.maxReqQueueCount = options.maxReqQueueCount || 100; | ||
this.parseUser = options.parseUser; | ||
@@ -81,3 +89,3 @@ | ||
var globalContext = this._globalContext = {}; | ||
var globalContext = (this._globalContext = {}); | ||
if (options.tags) { | ||
@@ -90,3 +98,3 @@ globalContext.tags = options.tags; | ||
this.onFatalError = this.defaultOnFatalError = function (err, sendErr, eventId) { | ||
this.onFatalError = this.defaultOnFatalError = function(err, sendErr, eventId) { | ||
console.error(err && err.stack ? err.stack : err); | ||
@@ -97,3 +105,3 @@ process.exit(1); | ||
this.on('error', function (err) { | ||
this.on('error', function(err) { | ||
utils.consoleAlert('failed to send exception to sentry: ' + err.message); | ||
@@ -116,4 +124,4 @@ }); | ||
var self = this; | ||
process.on('unhandledRejection', function (reason) { | ||
self.captureException(reason, function (sendErr, eventId) { | ||
process.on('unhandledRejection', function(reason) { | ||
self.captureException(reason, function(sendErr, eventId) { | ||
if (!sendErr) utils.consoleAlert('unhandledRejection captured: ' + eventId); | ||
@@ -145,3 +153,3 @@ }); | ||
makeErrorHandler: function () { | ||
makeErrorHandler: function() { | ||
var self = this; | ||
@@ -152,3 +160,3 @@ var caughtFirstError = false; | ||
var firstError; | ||
return function (err) { | ||
return function(err) { | ||
if (!caughtFirstError) { | ||
@@ -160,3 +168,3 @@ // this is the first uncaught error and the ultimate reason for shutting down | ||
caughtFirstError = true; | ||
self.captureException(err, function (sendErr, eventId) { | ||
self.captureException(err, function(sendErr, eventId) { | ||
if (!calledFatalError) { | ||
@@ -169,3 +177,5 @@ calledFatalError = true; | ||
// we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down | ||
utils.consoleAlert('uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown'); | ||
utils.consoleAlert( | ||
'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown' | ||
); | ||
self.defaultOnFatalError(err); | ||
@@ -188,3 +198,3 @@ } else if (!caughtSecondError) { | ||
caughtSecondError = true; | ||
setTimeout(function () { | ||
setTimeout(function() { | ||
if (!calledFatalError) { | ||
@@ -214,6 +224,11 @@ // it was probably case 1, let's treat err as the sendErr and call onFatalError | ||
var domainContext = domain.active && domain.active.sentryContext || {}; | ||
var domainContext = (domain.active && domain.active.sentryContext) || {}; | ||
kwargs.user = extend({}, this._globalContext.user, domainContext.user, kwargs.user); | ||
kwargs.tags = extend({}, this._globalContext.tags, domainContext.tags, kwargs.tags); | ||
kwargs.extra = extend({}, this._globalContext.extra, domainContext.extra, kwargs.extra); | ||
kwargs.extra = extend( | ||
{}, | ||
this._globalContext.extra, | ||
domainContext.extra, | ||
kwargs.extra | ||
); | ||
kwargs.breadcrumbs = { | ||
@@ -231,5 +246,13 @@ values: domainContext.breadcrumbs || this._globalContext.breadcrumbs || [] | ||
*/ | ||
kwargs.request = extend({}, this._globalContext.request, domainContext.request, kwargs.request); | ||
kwargs.request = this._createRequestObject( | ||
this._globalContext.request, | ||
domainContext.request, | ||
kwargs.request | ||
); | ||
if (Object.keys(kwargs.request).length === 0) { | ||
var req = extend({}, this._globalContext.req, domainContext.req, kwargs.req); | ||
var req = this._createRequestObject( | ||
this._globalContext.req, | ||
domainContext.req, | ||
kwargs.req | ||
); | ||
if (Object.keys(req).length > 0) { | ||
@@ -276,5 +299,6 @@ var parseUser = Object.keys(kwargs.user).length === 0 ? this.parseUser : false; | ||
// avoiding setImmediate here because node 0.8 | ||
cb && setTimeout(function () { | ||
cb(null, eventId); | ||
}, 0); | ||
cb && | ||
setTimeout(function() { | ||
cb(null, eventId); | ||
}, 0); | ||
} | ||
@@ -288,10 +312,14 @@ }, | ||
zlib.deflate(skwargs, function (err, buff) { | ||
zlib.deflate(skwargs, function(err, buff) { | ||
var message = buff.toString('base64'), | ||
timestamp = new Date().getTime(), | ||
headers = { | ||
'X-Sentry-Auth': utils.getAuthHeader(timestamp, self.dsn.public_key, self.dsn.private_key), | ||
'Content-Type': 'application/octet-stream', | ||
'Content-Length': message.length | ||
}; | ||
timestamp = new Date().getTime(), | ||
headers = { | ||
'X-Sentry-Auth': utils.getAuthHeader( | ||
timestamp, | ||
self.dsn.public_key, | ||
self.dsn.private_key | ||
), | ||
'Content-Type': 'application/octet-stream', | ||
'Content-Length': message.length | ||
}; | ||
@@ -332,3 +360,3 @@ self.transport.send(self, message, headers, eventId, cb); | ||
var eventId = this.generateEventId(); | ||
parsers.parseError(err, kwargs, function (kw) { | ||
parsers.parseError(err, kwargs, function(kw) { | ||
self.process(eventId, kw, cb); | ||
@@ -340,3 +368,3 @@ }); | ||
context: function (ctx, func) { | ||
context: function(ctx, func) { | ||
if (!func && typeof ctx === 'function') { | ||
@@ -353,3 +381,3 @@ func = ctx; | ||
wrap: function (options, func) { | ||
wrap: function(options, func) { | ||
if (!func && typeof options === 'function') { | ||
@@ -381,3 +409,3 @@ func = options; | ||
interceptErr: function (options, func) { | ||
interceptErr: function(options, func) { | ||
if (!func && typeof options === 'function') { | ||
@@ -388,3 +416,3 @@ func = options; | ||
var self = this; | ||
var wrapped = function () { | ||
var wrapped = function() { | ||
var err = arguments[0]; | ||
@@ -436,6 +464,6 @@ if (err instanceof Error) { | ||
setCallbackHelper: function (propertyName, callback) { | ||
setCallbackHelper: function(propertyName, callback) { | ||
var original = this[propertyName]; | ||
if (typeof callback === 'function') { | ||
this[propertyName] = function (data) { | ||
this[propertyName] = function(data) { | ||
return callback(data, original); | ||
@@ -457,3 +485,3 @@ }; | ||
*/ | ||
setDataCallback: function (callback) { | ||
setDataCallback: function(callback) { | ||
return this.setCallbackHelper('dataCallback', callback); | ||
@@ -469,10 +497,10 @@ }, | ||
*/ | ||
setShouldSendCallback: function (callback) { | ||
setShouldSendCallback: function(callback) { | ||
return this.setCallbackHelper('shouldSendCallback', callback); | ||
}, | ||
requestHandler: function () { | ||
requestHandler: function() { | ||
var self = this; | ||
return function (req, res, next) { | ||
self.context({ req: req }, function () { | ||
return function(req, res, next) { | ||
self.context({req: req}, function() { | ||
domain.active.add(req); | ||
@@ -485,5 +513,5 @@ domain.active.add(res); | ||
errorHandler: function () { | ||
errorHandler: function() { | ||
var self = this; | ||
return function (err, req, res, next) { | ||
return function(err, req, res, next) { | ||
var status = err.status || err.statusCode || err.status_code || 500; | ||
@@ -494,3 +522,3 @@ | ||
var eventId = self.captureException(err, { req: req }); | ||
var eventId = self.captureException(err, {req: req}); | ||
res.sentry = eventId; | ||
@@ -501,9 +529,12 @@ return next(err); | ||
captureBreadcrumb: function (breadcrumb) { | ||
captureBreadcrumb: function(breadcrumb) { | ||
// Avoid capturing global-scoped breadcrumbs before instrumentation finishes | ||
if (!this.installed) return; | ||
breadcrumb = extend({ | ||
timestamp: +new Date / 1000 | ||
}, breadcrumb); | ||
breadcrumb = extend( | ||
{ | ||
timestamp: +new Date() / 1000 | ||
}, | ||
breadcrumb | ||
); | ||
var currCtx = this.getContext(); | ||
@@ -516,2 +547,32 @@ if (!currCtx.breadcrumbs) currCtx.breadcrumbs = []; | ||
this.setContext(currCtx); | ||
}, | ||
_createRequestObject: function() { | ||
/** | ||
* When using proxy, some of the attributes of req/request objects are non-enumerable. | ||
* To make sure, that they are still available to us after we consolidate our sources | ||
* (eg. globalContext.request + domainContext.request + kwargs.request), | ||
* we manually pull them out from original objects. | ||
* | ||
* We don't use Object.assign/extend as it's only merging over objects own properties, | ||
* and we don't want to go through all of the properties as well, as we simply don't | ||
* need all of them. | ||
* | ||
* So far the only missing piece is `ip`, but we can specify what properties should | ||
* be pulled by extending `nonEnumerables` array. | ||
**/ | ||
var sources = Array.from(arguments).filter(function(source) { | ||
return Object.prototype.toString.call(source) === '[object Object]'; | ||
}); | ||
sources = [{}].concat(sources); | ||
var request = extend.apply(null, sources); | ||
var nonEnumberables = ['ip']; | ||
nonEnumberables.forEach(function(key) { | ||
sources.forEach(function(source) { | ||
if (source[key]) request[key] = source[key]; | ||
}); | ||
}); | ||
return request; | ||
} | ||
@@ -518,0 +579,0 @@ }); |
@@ -6,4 +6,4 @@ 'use strict'; | ||
module.exports = function (Raven, console, originals) { | ||
var wrapConsoleMethod = function (level) { | ||
module.exports = function(Raven, console, originals) { | ||
var wrapConsoleMethod = function(level) { | ||
if (!(level in console)) { | ||
@@ -13,19 +13,22 @@ return; | ||
utils.fill(console, level, function (originalConsoleLevel) { | ||
var sentryLevel = level === 'warn' | ||
? 'warning' | ||
: level; | ||
utils.fill( | ||
console, | ||
level, | ||
function(originalConsoleLevel) { | ||
var sentryLevel = level === 'warn' ? 'warning' : level; | ||
return function () { | ||
var args = [].slice.call(arguments); | ||
return function() { | ||
var args = [].slice.call(arguments); | ||
Raven.captureBreadcrumb({ | ||
message: util.format.apply(null, args), | ||
level: sentryLevel, | ||
category: 'console' | ||
}); | ||
Raven.captureBreadcrumb({ | ||
message: util.format.apply(null, args), | ||
level: sentryLevel, | ||
category: 'console' | ||
}); | ||
originalConsoleLevel.apply(console, args); | ||
}; | ||
}, originals); | ||
originalConsoleLevel.apply(console, args); | ||
}; | ||
}, | ||
originals | ||
); | ||
}; | ||
@@ -32,0 +35,0 @@ |
@@ -5,5 +5,5 @@ 'use strict'; | ||
module.exports = function (Raven, http, originals) { | ||
module.exports = function(Raven, http, originals) { | ||
var OrigClientRequest = http.ClientRequest; | ||
var ClientRequest = function (options, cb) { | ||
var ClientRequest = function(options, cb) { | ||
// Note: this won't capture a breadcrumb if a response never comes | ||
@@ -23,5 +23,7 @@ // It would be useful to know if that was the case, though, so | ||
} else { | ||
this.__ravenBreadcrumbUrl = (options.protocol || '') + '//' + | ||
(options.hostname || options.host || '') + | ||
(options.path || '/'); | ||
this.__ravenBreadcrumbUrl = | ||
(options.protocol || '') + | ||
'//' + | ||
(options.hostname || options.host || '') + | ||
(options.path || '/'); | ||
} | ||
@@ -31,4 +33,4 @@ }; | ||
utils.fill(ClientRequest.prototype, 'emit', function (origEmit) { | ||
return function (evt, maybeResp) { | ||
utils.fill(ClientRequest.prototype, 'emit', function(origEmit) { | ||
return function(evt, maybeResp) { | ||
if (evt === 'response' && this.__ravenBreadcrumbUrl) { | ||
@@ -51,5 +53,10 @@ if (!Raven.dsn || this.__ravenBreadcrumbUrl.indexOf(Raven.dsn.host) === -1) { | ||
utils.fill(http, 'ClientRequest', function () { | ||
return ClientRequest; | ||
}, originals); | ||
utils.fill( | ||
http, | ||
'ClientRequest', | ||
function() { | ||
return ClientRequest; | ||
}, | ||
originals | ||
); | ||
@@ -59,17 +66,27 @@ // http.request orig refs module-internal ClientRequest, not exported one, so | ||
// just get that reference updated to use our new ClientRequest | ||
utils.fill(http, 'request', function () { | ||
return function (options, cb) { | ||
return new http.ClientRequest(options, cb); | ||
}; | ||
}, originals); | ||
utils.fill( | ||
http, | ||
'request', | ||
function() { | ||
return function(options, cb) { | ||
return new http.ClientRequest(options, cb); | ||
}; | ||
}, | ||
originals | ||
); | ||
utils.fill(http, 'get', function () { | ||
return function (options, cb) { | ||
var req = http.request(options, cb); | ||
req.end(); | ||
return req; | ||
}; | ||
}, originals); | ||
utils.fill( | ||
http, | ||
'get', | ||
function() { | ||
return function(options, cb) { | ||
var req = http.request(options, cb); | ||
req.end(); | ||
return req; | ||
}; | ||
}, | ||
originals | ||
); | ||
return http; | ||
}; |
@@ -28,12 +28,17 @@ 'use strict'; | ||
var Module = require('module'); | ||
utils.fill(Module, '_load', function (origLoad) { | ||
return function (moduleId, parent, isMain) { | ||
var origModule = origLoad.apply(this, arguments); | ||
if (config[moduleId] && Raven.instrumentedModules.indexOf(moduleId) === -1) { | ||
Raven.instrumentedModules.push(moduleId); | ||
return require('./' + moduleId)(Raven, origModule, Raven.instrumentedOriginals); | ||
} | ||
return origModule; | ||
}; | ||
}, Raven.instrumentedOriginals); | ||
utils.fill( | ||
Module, | ||
'_load', | ||
function(origLoad) { | ||
return function(moduleId, parent, isMain) { | ||
var origModule = origLoad.apply(this, arguments); | ||
if (config[moduleId] && Raven.instrumentedModules.indexOf(moduleId) === -1) { | ||
Raven.instrumentedModules.push(moduleId); | ||
return require('./' + moduleId)(Raven, origModule, Raven.instrumentedOriginals); | ||
} | ||
return origModule; | ||
}; | ||
}, | ||
Raven.instrumentedOriginals | ||
); | ||
@@ -59,3 +64,3 @@ // special case: since console is built-in and app-level code won't require() it, do that here | ||
// eslint-disable-next-line no-cond-assign | ||
while (original = Raven.instrumentedOriginals.shift()) { | ||
while ((original = Raven.instrumentedOriginals.shift())) { | ||
var obj = original[0]; | ||
@@ -62,0 +67,0 @@ var name = original[1]; |
'use strict'; | ||
module.exports = function (Raven, pg, originals) { | ||
module.exports = function(Raven, pg, originals) { | ||
// Using fill helper here is hard because of `this` binding | ||
var origQuery = pg.Connection.prototype.query; | ||
pg.Connection.prototype.query = function (text) { | ||
pg.Connection.prototype.query = function(text) { | ||
Raven.captureBreadcrumb({ | ||
@@ -7,0 +7,0 @@ category: 'postgres', |
@@ -5,3 +5,3 @@ 'use strict'; | ||
var urlParser = require('url'); | ||
var stringify = require('json-stringify-safe'); | ||
var stringify = require('../vendor/json-stringify-safe'); | ||
@@ -18,14 +18,17 @@ var utils = require('./utils'); | ||
module.exports.parseError = function parseError(err, kwargs, cb) { | ||
utils.parseStack(err, function (frames) { | ||
var name = err.name + ''; | ||
utils.parseStack(err, function(frames) { | ||
var name = | ||
({}.hasOwnProperty.call(err, 'name') ? err.name : err.constructor.name) + ''; | ||
if (typeof kwargs.message === 'undefined') { | ||
kwargs.message = name + ': ' + (err.message || '<no message>'); | ||
} | ||
kwargs.exception = [{ | ||
type: name, | ||
value: err.message, | ||
stacktrace: { | ||
frames: frames | ||
kwargs.exception = [ | ||
{ | ||
type: name, | ||
value: err.message, | ||
stacktrace: { | ||
frames: frames | ||
} | ||
} | ||
}]; | ||
]; | ||
@@ -79,3 +82,6 @@ // Save additional error properties to `extra` under the error type (e.g. `extra.AttributeError`) | ||
// express, koa: req.protocol | ||
var protocol = req.protocol === 'https' || req.secure || (req.socket || {}).encrypted ? 'https' : 'http'; | ||
var protocol = | ||
req.protocol === 'https' || req.secure || (req.socket || {}).encrypted | ||
? 'https' | ||
: 'http'; | ||
@@ -146,3 +152,3 @@ // url (including path and query string): | ||
} else { | ||
parseUser.forEach(function (fieldName) { | ||
parseUser.forEach(function(fieldName) { | ||
if ({}.hasOwnProperty.call(req.user, fieldName)) { | ||
@@ -158,3 +164,3 @@ user[fieldName] = req.user[fieldName]; | ||
// express, koa: req.ip | ||
var ip = req.ip || req.connection && req.connection.remoteAddress; | ||
var ip = req.ip || (req.connection && req.connection.remoteAddress); | ||
if (ip) { | ||
@@ -161,0 +167,0 @@ user.ip_address = ip; |
@@ -10,2 +10,6 @@ 'use strict'; | ||
var agentOptions = {keepAlive: true, maxSockets: 100}; | ||
var httpAgent = new http.Agent(agentOptions); | ||
var httpsAgent = new https.Agent(agentOptions); | ||
function Transport() {} | ||
@@ -18,5 +22,6 @@ util.inherits(Transport, events.EventEmitter); | ||
this.options = options || {}; | ||
this.agent = httpAgent; | ||
} | ||
util.inherits(HTTPTransport, Transport); | ||
HTTPTransport.prototype.send = function (client, message, headers, eventId, cb) { | ||
HTTPTransport.prototype.send = function(client, message, headers, eventId, cb) { | ||
var options = { | ||
@@ -28,3 +33,4 @@ hostname: client.dsn.host, | ||
port: client.dsn.port || this.defaultPort, | ||
ca: client.ca | ||
ca: client.ca, | ||
agent: this.agent | ||
}; | ||
@@ -37,3 +43,12 @@ for (var key in this.options) { | ||
var req = this.transport.request(options, function (res) { | ||
// prevent off heap memory explosion | ||
var _name = this.agent.getName({host: client.dsn.host, port: client.dsn.port}); | ||
var _requests = this.agent.requests[_name]; | ||
if (_requests && Object.keys(_requests).length > client.maxReqQueueCount) { | ||
// other feedback strategy | ||
client.emit('error', new Error('client req queue is full..')); | ||
return; | ||
} | ||
var req = this.transport.request(options, function(res) { | ||
res.setEncoding('utf8'); | ||
@@ -55,4 +70,5 @@ if (res.statusCode >= 200 && res.statusCode < 300) { | ||
} | ||
// force the socket to drain | ||
var noop = function () {}; | ||
var noop = function() {}; | ||
res.on('data', noop); | ||
@@ -65,3 +81,3 @@ res.on('end', noop); | ||
var cbFired = false; | ||
req.on('error', function (e) { | ||
req.on('error', function(e) { | ||
client.emit('error', e); | ||
@@ -80,2 +96,3 @@ if (!cbFired) { | ||
this.options = options || {}; | ||
this.agent = httpsAgent; | ||
} | ||
@@ -82,0 +99,0 @@ util.inherits(HTTPSTransport, HTTPTransport); |
@@ -36,13 +36,15 @@ 'use strict'; | ||
module.exports.extend = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
module.exports.extend = | ||
Object.assign || | ||
function(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return target; | ||
}; | ||
@@ -54,3 +56,3 @@ module.exports.getAuthHeader = function getAuthHeader(timestamp, apiKey, apiSecret) { | ||
header.push('sentry_key=' + apiKey); | ||
header.push('sentry_secret=' + apiSecret); | ||
if (apiSecret) header.push('sentry_secret=' + apiSecret); | ||
return header.join(', '); | ||
@@ -66,9 +68,12 @@ }; | ||
var parsed = url.parse(dsn), | ||
response = { | ||
protocol: parsed.protocol.slice(0, -1), | ||
public_key: parsed.auth.split(':')[0], | ||
private_key: parsed.auth.split(':')[1], | ||
host: parsed.host.split(':')[0] | ||
}; | ||
response = { | ||
protocol: parsed.protocol.slice(0, -1), | ||
public_key: parsed.auth.split(':')[0], | ||
host: parsed.host.split(':')[0] | ||
}; | ||
if (parsed.auth.split(':')[1]) { | ||
response.private_key = parsed.auth.split(':')[1]; | ||
} | ||
if (~response.protocol.indexOf('+')) { | ||
@@ -107,3 +112,3 @@ response.protocol = response.protocol.split('+')[1]; | ||
module.exports.fill = function (obj, name, replacement, track) { | ||
module.exports.fill = function(obj, name, replacement, track) { | ||
var orig = obj[name]; | ||
@@ -120,4 +125,6 @@ obj[name] = replacement(orig); | ||
try { | ||
return line.getFunctionName() || | ||
line.getTypeName() + '.' + (line.getMethodName() || '<anonymous>'); | ||
return ( | ||
line.getFunctionName() || | ||
line.getTypeName() + '.' + (line.getMethodName() || '<anonymous>') | ||
); | ||
} catch (e) { | ||
@@ -131,3 +138,5 @@ // This seems to happen sometimes when using 'use strict', | ||
var mainModule = (require.main && require.main.filename && path.dirname(require.main.filename) || process.cwd()) + '/'; | ||
var mainModule = | ||
((require.main && require.main.filename && path.dirname(require.main.filename)) || | ||
process.cwd()) + '/'; | ||
@@ -163,4 +172,4 @@ function getModule(filename, base) { | ||
var numFilesToRead = filenames.length; | ||
return filenames.forEach(function (filename) { | ||
fs.readFile(filename, function (readErr, file) { | ||
return filenames.forEach(function(filename) { | ||
fs.readFile(filename, function(readErr, file) { | ||
if (!readErr) sourceFiles[filename] = file.toString().split('\n'); | ||
@@ -210,3 +219,3 @@ if (--numFilesToRead === 0) cb(sourceFiles); | ||
var filesToRead = {}; | ||
stack.forEach(function (line) { | ||
stack.forEach(function(line) { | ||
var frame = { | ||
@@ -216,9 +225,10 @@ filename: line.getFileName() || '', | ||
colno: line.getColumnNumber(), | ||
'function': getFunction(line), | ||
function: getFunction(line) | ||
}; | ||
var isInternal = line.isNative() || | ||
frame.filename[0] !== '/' && | ||
frame.filename[0] !== '.' && | ||
frame.filename.indexOf(':\\') !== 1; | ||
var isInternal = | ||
line.isNative() || | ||
(frame.filename[0] !== '/' && | ||
frame.filename[0] !== '.' && | ||
frame.filename.indexOf(':\\') !== 1); | ||
@@ -239,10 +249,14 @@ // in_app is all that's not an internal Node function or a module within node_modules | ||
return readSourceFiles(Object.keys(filesToRead), function (sourceFiles) { | ||
frames.forEach(function (frame) { | ||
return readSourceFiles(Object.keys(filesToRead), function(sourceFiles) { | ||
frames.forEach(function(frame) { | ||
if (frame.filename && sourceFiles[frame.filename]) { | ||
var lines = sourceFiles[frame.filename]; | ||
try { | ||
frame.pre_context = lines.slice(Math.max(0, frame.lineno - (LINES_OF_CONTEXT + 1)), frame.lineno - 1).map(snipLine0); | ||
frame.pre_context = lines | ||
.slice(Math.max(0, frame.lineno - (LINES_OF_CONTEXT + 1)), frame.lineno - 1) | ||
.map(snipLine0); | ||
frame.context_line = snipLine(lines[frame.lineno - 1], frame.colno); | ||
frame.post_context = lines.slice(frame.lineno, frame.lineno + LINES_OF_CONTEXT).map(snipLine0); | ||
frame.post_context = lines | ||
.slice(frame.lineno, frame.lineno + LINES_OF_CONTEXT) | ||
.map(snipLine0); | ||
} catch (e) { | ||
@@ -249,0 +263,0 @@ // anomaly, being defensive in case |
@@ -5,14 +5,15 @@ { | ||
"keywords": [ | ||
"debugging", | ||
"errors", | ||
"exceptions", | ||
"logging", | ||
"raven", | ||
"sentry", | ||
"python", | ||
"errors", | ||
"debugging", | ||
"exceptions" | ||
"sentry" | ||
], | ||
"version": "2.1.2", | ||
"version": "2.2.0", | ||
"repository": "git://github.com/getsentry/raven-node.git", | ||
"license": "BSD-2-Clause", | ||
"homepage": "https://github.com/getsentry/raven-node", | ||
"author": "Matt Robenolt <matt@ydekproductions.com>", | ||
"license": "BSD-2-Clause", | ||
"main": "index", | ||
"main": "index.js", | ||
"bin": { | ||
@@ -22,15 +23,16 @@ "raven": "./bin/raven" | ||
"scripts": { | ||
"lint": "node_modules/eslint/bin/eslint.js .", | ||
"precommit": "lint-staged", | ||
"pretest": "npm install && npm run lint", | ||
"test": "NODE_ENV=test istanbul cover _mocha -- --reporter dot && NODE_ENV=test node_modules/coffee-script/bin/coffee ./test/run.coffee", | ||
"test-mocha": "NODE_ENV=test mocha", | ||
"test-full": "npm run test && cd test/instrumentation && ./run.sh", | ||
"lint": "node_modules/eslint/bin/eslint.js ." | ||
"test-full": "npm run test && cd test/instrumentation && ./run.sh" | ||
}, | ||
"engines": { | ||
"node": ">= 0.8.0" | ||
"node": ">= 4.0.0" | ||
}, | ||
"dependencies": { | ||
"cookie": "0.3.1", | ||
"json-stringify-safe": "5.0.1", | ||
"lsmod": "1.0.0", | ||
"memwatch-next": "^0.3.0", | ||
"stack-trace": "0.0.9", | ||
@@ -43,11 +45,26 @@ "timed-out": "4.0.1", | ||
"connect": "*", | ||
"eslint": "2.13.1", | ||
"eslint": "^4.5.0", | ||
"eslint-config-prettier": "^2.3.0", | ||
"express": "*", | ||
"glob": "~3.1.13", | ||
"husky": "^0.14.3", | ||
"istanbul": "^0.4.3", | ||
"koa": "*", | ||
"lint-staged": "^4.0.4", | ||
"mocha": "~3.1.2", | ||
"nock": "~9.0.0", | ||
"should": "11.2.0" | ||
"prettier": "^1.6.1", | ||
"should": "11.2.0", | ||
"sinon": "^3.3.0" | ||
}, | ||
"prettier": { | ||
"singleQuote": true, | ||
"bracketSpacing": false, | ||
"printWidth": 90 | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"prettier --write", | ||
"git add" | ||
] | ||
} | ||
} |
@@ -1,5 +0,17 @@ | ||
# raven-node [![Build Status](https://travis-ci.org/getsentry/raven-node.svg?branch=master)](https://travis-ci.org/getsentry/raven-node) | ||
<p align="center"> | ||
<a href="https://sentry.io" target="_blank" align="center"> | ||
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280"> | ||
</a> | ||
<br/> | ||
<h1>Raven-node - Sentry SDK for Node.js</h1> | ||
</p> | ||
raven-node is a Node.js client for [Sentry](https://getsentry.com/). | ||
[![Build Status](https://travis-ci.org/getsentry/raven-node.svg?branch=master)](https://travis-ci.org/getsentry/raven-node) | ||
`raven-node` supports only LTS versions of Node, therefore currently required release is `>= v4.0.0`. | ||
The last known working version for `v0.10` and `v0.12` is `raven-node@2.1.2`. | ||
Please use this version if you need to support those releases of Node. | ||
To see up-to-date Node.js LTS Release Schedule, go to https://github.com/nodejs/LTS. | ||
## Resources | ||
@@ -6,0 +18,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
58767
15
1193
0
22
14
10
4
+ Addedmemwatch-next@^0.3.0
+ Addedbindings@1.5.0(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addedmemwatch-next@0.3.0(transitive)
+ Addednan@2.20.0(transitive)
- Removedjson-stringify-safe@5.0.1
- Removedjson-stringify-safe@5.0.1(transitive)