Socket
Socket
Sign inDemoInstall

raven

Package Overview
Dependencies
Maintainers
4
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

raven - npm Package Compare versions

Comparing version 1.2.1 to 2.0.0

15

History.md

@@ -0,1 +1,16 @@

# 2.0.0 - 5/10/2017
- Properly surface errors to preserve process exit conditions [See #308, #257]
- Node processes with raven will now exit in exactly the same situations as if raven were not present
- Previously, there were failure scenarios where raven would erroneously cause the process to continue to run when it should have shut down
- **Be aware when upgrading:** it is possible that with raven-node 2.0, your node process will shut down from exceptions where it previously did not
- This also includes changes to more reliably finish capturing the exception that induces process shutdown
- Don't include `domain` property as extra property on `Error` objects [See #309]
- Parse `req` object from context or kwargs [See #310]
- For Express middleware users in particular, raven will now automatically report request details and user context in situations where it previously did not
- Tidied up `.npmignore` to exclude unnecessary files in npm package [See #311]
- Install size reduced from 484kB to 84kB, which should save npm ~100GB/month in bandwidth
- Removed various deprecated methods [See #313]
- Removed postgres autoBreadcrumbs to avoid webpack dependency issue [See #315, #254]
- postgres (and more) autoBreadcrumbs will return in version 2.1
# 1.1.6, 1.2.1 - 4/7/2017

@@ -2,0 +17,0 @@ - Fix memory leak in `consoleAlert` (and thus, if not disabled, in `captureException`) [See #300]

6

index.js

@@ -5,7 +5,3 @@ 'use strict';

module.exports.utils = require('./lib/utils');
module.exports.middleware = {
connect: require('./lib/middleware/connect')
};
// friendly alias for "raven.middleware.express"
module.exports.middleware.express = module.exports.middleware.connect;
module.exports.transports = require('./lib/transports');

@@ -12,0 +8,0 @@ module.exports.parsers = require('./lib/parsers');

@@ -116,16 +116,2 @@ 'use strict';

}, originals);
},
pg: function (Raven) {
// Using fill helper here is hard because of `this` binding
var pg = require('pg');
var origQuery = pg.Connection.prototype.query;
pg.Connection.prototype.query = function (text) {
Raven.captureBreadcrumb({
category: 'postgres',
message: text
});
origQuery.call(this, text);
};
originals.push([pg.Connection.prototype, 'query', origQuery]);
}

@@ -132,0 +118,0 @@ };

@@ -48,2 +48,3 @@ 'use strict';

this.transport = options.transport || transports[this.dsn.protocol];
this.sendTimeout = options.sendTimeout || 1;
this.release = options.release || process.env.SENTRY_RELEASE || '';

@@ -59,3 +60,2 @@ this.environment = options.environment || process.env.SENTRY_ENVIRONMENT || '';

http: false,
pg: false
};

@@ -104,2 +104,8 @@ // default to 30, don't allow higher than 100

this.onFatalError = this.defaultOnFatalError = function (err, sendErr, eventId) {
console.error(err && err.stack ? err.stack : err);
process.exit(1);
};
this.uncaughtErrorHandler = this.makeErrorHandler();
this.on('error', function (err) {

@@ -112,12 +118,18 @@ utils.consoleAlert('failed to send exception to sentry: ' + err.message);

install: function install(opts, cb) {
install: function install(cb) {
if (this.installed) return this;
if (typeof opts === 'function') {
cb = opts;
if (typeof cb === 'function') {
this.onFatalError = cb;
}
registerExceptionHandler(this, cb);
process.on('uncaughtException', this.uncaughtErrorHandler);
if (this.captureUnhandledRejections) {
registerRejectionHandler(this, cb);
var self = this;
process.on('unhandledRejection', function (reason) {
self.captureException(reason, function (sendErr, eventId) {
if (!sendErr) utils.consoleAlert('unhandledRejection captured: ' + eventId);
});
});
}

@@ -150,2 +162,54 @@

makeErrorHandler: function () {
var self = this;
var caughtFirstError = false;
var caughtSecondError = false;
var calledFatalError = false;
var firstError;
return function (err) {
if (!caughtFirstError) {
// this is the first uncaught error and the ultimate reason for shutting down
// we want to do absolutely everything possible to ensure it gets captured
// also we want to make sure we don't go recursion crazy if more errors happen after this one
firstError = err;
caughtFirstError = true;
self.captureException(err, function (sendErr, eventId) {
if (!calledFatalError) {
calledFatalError = true;
self.onFatalError(err, sendErr, eventId);
}
});
} else if (calledFatalError) {
// 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');
self.defaultOnFatalError(err);
} else if (!caughtSecondError) {
// two cases for how we can hit this branch:
// - capturing of first error blew up and we just caught the exception from that
// - quit trying to capture, proceed with shutdown
// - a second independent error happened while waiting for first error to capture
// - want to avoid causing premature shutdown before first error capture finishes
// it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff
// so let's instead just delay a bit before we proceed with our action here
// in case 1, we just wait a bit unnecessarily but ultimately do the same thing
// in case 2, the delay hopefully made us wait long enough for the capture to finish
// two potential nonideal outcomes:
// nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError
// nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error
// note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError)
// we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish
caughtSecondError = true;
setTimeout(function () {
if (!calledFatalError) {
// it was probably case 1, let's treat err as the sendErr and call onFatalError
calledFatalError = true;
self.onFatalError(firstError, err);
} else {
// it was probably case 2, our first error finished capturing while we waited, cool, do nothing
}
}, (self.sendTimeout + 1) * 1000); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc
}
};
},
generateEventId: function generateEventId() {

@@ -171,2 +235,17 @@ return uuid().replace(/-/g, '');

/*
`request` is our specified property name for the http interface: https://docs.sentry.io/clientdev/interfaces/http/
`req` is the conventional name for a request object in node/express/etc
we want to enable someone to pass a `request` property to kwargs according to http interface
but also want to provide convenience for passing a req object and having us parse it out
so we only parse a `req` property if the `request` property is absent/empty (and hence we won't clobber)
parseUser returns a partial kwargs object with a `request` property and possibly a `user` property
*/
kwargs.request = extend({}, 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 parseUser = Object.keys(kwargs.user).length === 0 ? this.parseUser : false;
kwargs = extend(kwargs, parsers.parseRequest(req, parseUser));
}
kwargs.modules = utils.getModules();

@@ -267,8 +346,3 @@ kwargs.server_name = kwargs.server_name || this.name;

/* The onErr param here is sort of ugly and won't typically be used
* but it lets us write the requestHandler middleware in terms of this function.
* We could consider getting rid of it and just duplicating the domain
* instantiation etc logic in the requestHandler middleware
*/
context: function (ctx, func, onErr) {
context: function (ctx, func) {
if (!func && typeof ctx === 'function') {

@@ -282,6 +356,6 @@ func = ctx;

// and i don't know if we need to support the args param; it's undocumented
return this.wrap(ctx, func, onErr).apply(null);
return this.wrap(ctx, func).apply(null);
},
wrap: function (options, func, onErr) {
wrap: function (options, func) {
if (!func && typeof options === 'function') {

@@ -296,10 +370,3 @@ func = options;

var self = this;
if (typeof onErr !== 'function') {
onErr = function (err) {
self.captureException(err);
};
}
wrapDomain.on('error', onErr);
wrapDomain.on('error', this.uncaughtErrorHandler);
var wrapped = wrapDomain.bind(func);

@@ -412,7 +479,7 @@

return function (req, res, next) {
self.context({}, function () {
self.context({ req: req }, function () {
domain.active.add(req);
domain.active.add(res);
next();
}, next);
});
};

@@ -429,4 +496,3 @@ },

var kwargs = parsers.parseRequest(req, self.parseUser);
var eventId = self.captureException(err, kwargs);
var eventId = self.captureException(err, { req: req });
res.sentry = eventId;

@@ -456,36 +522,2 @@ return next(err);

// Deprecations
extend(Raven.prototype, {
getIdent: function getIdent(result) {
utils.consoleAlertOnce('getIdent has been deprecated and will be removed in v2.0');
return result;
},
captureError: function captureError() {
utils.consoleAlertOnce('captureError has been deprecated and will be removed in v2.0; use captureException instead');
return this.captureException.apply(this, arguments);
},
captureQuery: function captureQuery() {
utils.consoleAlertOnce('captureQuery has been deprecated and will be removed in v2.0');
return this;
},
patchGlobal: function (cb) {
utils.consoleAlertOnce('patchGlobal has been deprecated and will be removed in v2.0; use install instead');
registerExceptionHandler(this, cb);
return this;
},
setUserContext: function setUserContext() {
utils.consoleAlertOnce('setUserContext has been deprecated and will be removed in v2.0; use setContext instead');
return this;
},
setExtraContext: function setExtraContext() {
utils.consoleAlertOnce('setExtraContext has been deprecated and will be removed in v2.0; use setContext instead');
return this;
},
setTagsContext: function setTagsContext() {
utils.consoleAlertOnce('setTagsContext has been deprecated and will be removed in v2.0; use setContext instead');
return this;
},
});
Raven.prototype.get_ident = Raven.prototype.getIdent;
// Maintain old API compat, need to make sure arguments length is preserved

@@ -503,3 +535,2 @@ function Client(dsn, options) {

defaultInstance.Client = Client;
defaultInstance.patchGlobal = patchGlobal;
defaultInstance.version = require('../package.json').version;

@@ -509,56 +540,1 @@ defaultInstance.disableConsoleAlerts = utils.disableConsoleAlerts;

module.exports = defaultInstance;
function registerExceptionHandler(client, cb) {
var called = false;
process.on('uncaughtException', function (err) {
if (cb) { // bind event listeners only if a callback was supplied
var onLogged = function onLogged() {
called = false;
cb(true, err);
};
var onError = function onError() {
called = false;
cb(false, err);
};
if (called) {
client.removeListener('logged', onLogged);
client.removeListener('error', onError);
return cb(false, err);
}
client.once('logged', onLogged);
client.once('error', onError);
called = true;
}
var eventId = client.captureException(err);
return utils.consoleAlert('uncaughtException: ' + eventId);
});
}
function registerRejectionHandler(client, cb) {
process.on('unhandledRejection', function (reason) {
var eventId = client.captureException(reason, function (sendErr) {
cb && cb(!sendErr, reason);
});
return utils.consoleAlert('unhandledRejection: ' + eventId);
});
}
function patchGlobal(client, cb) {
// handle when the first argument is the callback, with no client specified
if (typeof client === 'function') {
cb = client;
client = new Client();
// first argument is a string DSN
} else if (typeof client === 'string') {
client = new Client(client);
}
// at the end, if we still don't have a Client, let's make one!
!(client instanceof Raven) && (client = new Client());
registerExceptionHandler(client, cb);
}

@@ -34,3 +34,3 @@ 'use strict';

if (err.hasOwnProperty(key)) {
if (key !== 'name' && key !== 'message' && key !== 'stack') {
if (key !== 'name' && key !== 'message' && key !== 'stack' && key !== 'domain') {
extraErrorProps = extraErrorProps || {};

@@ -37,0 +37,0 @@ extraErrorProps[key] = err[key];

@@ -5,8 +5,10 @@ 'use strict';

var util = require('util');
var timeoutReq = require('timed-out');
var http = require('http');
var https = require('https');
function Transport() {}
util.inherits(Transport, events.EventEmitter);
var http = require('http');
function HTTPTransport(options) {

@@ -32,2 +34,3 @@ this.defaultPort = 80;

}
var req = this.transport.request(options, function (res) {

@@ -56,2 +59,4 @@ res.setEncoding('utf8');

timeoutReq(req, client.sendTimeout * 1000);
var cbFired = false;

@@ -68,4 +73,2 @@ req.on('error', function (e) {

var https = require('https');
function HTTPSTransport(options) {

@@ -72,0 +75,0 @@ this.defaultPort = 443;

@@ -12,3 +12,3 @@ {

],
"version": "1.2.1",
"version": "2.0.0",
"repository": "git://github.com/getsentry/raven-node.git",

@@ -36,3 +36,4 @@ "author": "Matt Robenolt <matt@ydekproductions.com>",

"uuid": "3.0.0",
"stack-trace": "0.0.9"
"stack-trace": "0.0.9",
"timed-out": "4.0.1"
},

@@ -39,0 +40,0 @@ "devDependencies": {

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