raven
Version:
A standalone (Node.js) client for Sentry
93 lines (84 loc) • 2.95 kB
JavaScript
var util = require('util');
var utils = require('../utils');
module.exports = function(Raven, http, originals) {
var OrigClientRequest = http.ClientRequest;
var ClientRequest = function(options, cb) {
// Note: this won't capture a breadcrumb if a response never comes
// It would be useful to know if that was the case, though, so
// todo: revisit to see if we can capture sth indicating response never came
// possibility: capture one breadcrumb for "req sent" and one for "res recvd"
// seems excessive but solves the problem and *is* strictly more information
// could be useful for weird response sequencing bug scenarios
OrigClientRequest.call(this, options, cb);
// We could just always reconstruct this from this.agent, this._headers, this.path, etc
// but certain other http-instrumenting libraries (like nock, which we use for tests) fail to
// maintain the guarantee that after calling OrigClientRequest, those fields will be populated
if (typeof options === 'string') {
this.__ravenBreadcrumbUrl = options;
} else {
var protocol = options.protocol || '';
var hostname = options.hostname || options.host || '';
// Don't log standard :80 (http) and :443 (https) ports to reduce the noise
var port =
!options.port || options.port === 80 || options.port === 443
? ''
: ':' + options.port;
var path = options.path || '/';
this.__ravenBreadcrumbUrl = protocol + '//' + hostname + port + path;
}
};
util.inherits(ClientRequest, OrigClientRequest);
utils.fill(ClientRequest.prototype, 'emit', function(origEmit) {
return function(evt, maybeResp) {
if (evt === 'response' && this.__ravenBreadcrumbUrl) {
if (!Raven.dsn || this.__ravenBreadcrumbUrl.indexOf(Raven.dsn.host) === -1) {
Raven.captureBreadcrumb({
type: 'http',
category: 'http',
data: {
method: this.method,
url: this.__ravenBreadcrumbUrl,
status_code: maybeResp.statusCode
}
});
}
}
return origEmit.apply(this, arguments);
};
});
utils.fill(
http,
'ClientRequest',
function() {
return ClientRequest;
},
originals
);
// http.request orig refs module-internal ClientRequest, not exported one, so
// it still points at orig ClientRequest after our monkeypatch; these reimpls
// 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,
'get',
function() {
return function(options, cb) {
var req = http.request(options, cb);
req.end();
return req;
};
},
originals
);
return http;
};
;