Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sentry/node

Package Overview
Dependencies
Maintainers
12
Versions
536
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sentry/node - npm Package Compare versions

Comparing version 5.7.1 to 5.8.0-beta.0

5

dist/handlers.d.ts
/// <reference types="node" />
import { Event } from '@sentry/types';
import * as http from 'http';
/**
* Express compatible tracing handler.
* @see Exposed as `Handlers.tracingHandler`
*/
export declare function tracingHandler(): (req: http.IncomingMessage, res: http.ServerResponse, next: (error?: any) => void) => void;
declare type TransactionTypes = 'path' | 'methodPath' | 'handler';

@@ -5,0 +10,0 @@ /**

39

dist/handlers.js
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var core_1 = require("@sentry/core");
var hub_1 = require("@sentry/hub");
var utils_1 = require("@sentry/utils");

@@ -12,2 +11,32 @@ var cookie = require("cookie");

var DEFAULT_SHUTDOWN_TIMEOUT = 2000;
/**
* Express compatible tracing handler.
* @see Exposed as `Handlers.tracingHandler`
*/
function tracingHandler() {
return function sentryTracingMiddleware(req, res, next) {
// TODO: At this point req.route.path we use in `extractTransaction` is not available
// but `req.path` or `req.url` should do the job as well. We could unify this here.
var reqMethod = (req.method || '').toUpperCase();
var reqUrl = req.url;
var hub = core_1.getCurrentHub();
var transaction = hub.startSpan({
transaction: reqMethod + "|" + reqUrl,
});
hub.configureScope(function (scope) {
scope.setSpan(transaction);
});
res.once('finish', function () {
if (res.statusCode >= 500) {
transaction.setFailure();
}
else {
transaction.setSuccess();
}
transaction.finish();
});
next();
};
}
exports.tracingHandler = tracingHandler;
/** JSDoc */

@@ -213,12 +242,12 @@ function extractTransaction(req, type) {

function errorHandler(options) {
return function sentryErrorMiddleware(error, _req, _res, next) {
return function sentryErrorMiddleware(error, req, res, next) {
var shouldHandleError = (options && options.shouldHandleError) || defaultShouldHandleError;
if (shouldHandleError(error)) {
core_1.withScope(function (scope) {
if (_req.headers && utils_1.isString(_req.headers['sentry-trace'])) {
var span = hub_1.Span.fromTraceparent(_req.headers['sentry-trace']);
if (req.headers && utils_1.isString(req.headers['sentry-trace'])) {
var span = core_1.Span.fromTraceparent(req.headers['sentry-trace']);
scope.setSpan(span);
}
var eventId = core_1.captureException(error);
_res.sentry = eventId;
res.sentry = eventId;
next(error);

@@ -225,0 +254,0 @@ });

2

dist/index.d.ts
export { Breadcrumb, Request, SdkInfo, Event, Exception, Response, Severity, StackFrame, Stacktrace, Status, Thread, User, } from '@sentry/types';
export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, getCurrentHub, getHubFromCarrier, Hub, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, Span, withScope, } from '@sentry/core';
export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, getHubFromCarrier, getCurrentHub, Hub, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startSpan, Span, withScope, } from '@sentry/core';
export { NodeOptions } from './backend';

@@ -4,0 +4,0 @@ export { NodeClient } from './client';

@@ -13,4 +13,4 @@ Object.defineProperty(exports, "__esModule", { value: true });

exports.configureScope = core_1.configureScope;
exports.getHubFromCarrier = core_1.getHubFromCarrier;
exports.getCurrentHub = core_1.getCurrentHub;
exports.getHubFromCarrier = core_1.getHubFromCarrier;
exports.Hub = core_1.Hub;

@@ -24,2 +24,3 @@ exports.Scope = core_1.Scope;

exports.setUser = core_1.setUser;
exports.startSpan = core_1.startSpan;
exports.Span = core_1.Span;

@@ -26,0 +27,0 @@ exports.withScope = core_1.withScope;

@@ -19,6 +19,17 @@ Object.defineProperty(exports, "__esModule", { value: true });

Console.prototype.setupOnce = function () {
var nativeModule = require('module');
utils_1.fill(nativeModule, '_load', loadWrapper(nativeModule));
// special case: since console is built-in and app-level code won't require() it, do that here
require('console');
var e_1, _a;
var consoleModule = require('console');
try {
for (var _b = tslib_1.__values(['debug', 'info', 'warn', 'error', 'log']), _c = _b.next(); !_c.done; _c = _b.next()) {
var level = _c.value;
utils_1.fill(consoleModule, level, createConsoleWrapper(level));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};

@@ -33,62 +44,38 @@ /**

/**
* Wrapper function for internal _load calls within `require`
*/
function loadWrapper(nativeModule) {
// We need to use some functional-style currying to pass values around
// as we cannot rely on `bind`, because this has to preserve correct
// context for native calls
return function (originalLoad) {
return function (moduleId) {
var originalModule = originalLoad.apply(nativeModule, arguments);
if (moduleId !== 'console' || originalModule.__sentry__) {
return originalModule;
}
['debug', 'info', 'warn', 'error', 'log'].forEach(consoleWrapper(originalModule));
originalModule.__sentry__ = true;
return originalModule;
};
};
}
/**
* Wrapper function that'll be used for every console level
*/
function consoleWrapper(originalModule) {
return function (level) {
if (!(level in originalModule)) {
return;
function createConsoleWrapper(level) {
return function consoleWrapper(originalConsoleMethod) {
var sentryLevel;
switch (level) {
case 'debug':
sentryLevel = types_1.Severity.Debug;
break;
case 'error':
sentryLevel = types_1.Severity.Error;
break;
case 'info':
sentryLevel = types_1.Severity.Info;
break;
case 'warn':
sentryLevel = types_1.Severity.Warning;
break;
default:
sentryLevel = types_1.Severity.Log;
}
utils_1.fill(originalModule, level, function (originalConsoleLevel) {
var sentryLevel;
switch (level) {
case 'debug':
sentryLevel = types_1.Severity.Debug;
break;
case 'error':
sentryLevel = types_1.Severity.Error;
break;
case 'info':
sentryLevel = types_1.Severity.Info;
break;
case 'warn':
sentryLevel = types_1.Severity.Warning;
break;
default:
sentryLevel = types_1.Severity.Log;
return function () {
if (core_1.getCurrentHub().getIntegration(Console)) {
core_1.getCurrentHub().addBreadcrumb({
category: 'console',
level: sentryLevel,
message: util.format.apply(undefined, arguments),
}, {
input: tslib_1.__spread(arguments),
level: level,
});
}
return function () {
if (core_1.getCurrentHub().getIntegration(Console)) {
core_1.getCurrentHub().addBreadcrumb({
category: 'console',
level: sentryLevel,
message: util.format.apply(undefined, arguments),
}, {
input: tslib_1.__spread(arguments),
level: level,
});
}
originalConsoleLevel.apply(originalModule, arguments);
};
});
originalConsoleMethod.apply(this, arguments);
};
};
}
//# sourceMappingURL=console.js.map

@@ -15,4 +15,19 @@ import { Integration } from '@sentry/types';

*/
private readonly _breadcrumbs;
/**
* @inheritDoc
*/
private readonly _tracing;
/**
* @inheritDoc
*/
constructor(options?: {
breadcrumbs?: boolean;
tracing?: boolean;
});
/**
* @inheritDoc
*/
setupOnce(): void;
}
//# sourceMappingURL=http.d.ts.map
Object.defineProperty(exports, "__esModule", { value: true });
var core_1 = require("@sentry/core");
var utils_1 = require("@sentry/utils");
var util = require("util");
var lastResponse;
var NODE_VERSION = utils_1.parseSemver(process.versions.node);
/** http module integration */
var Http = /** @class */ (function () {
function Http() {
/**
* @inheritDoc
*/
function Http(options) {
if (options === void 0) { options = {}; }
/**

@@ -13,2 +16,4 @@ * @inheritDoc

this.name = Http.id;
this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;
this._tracing = typeof options.tracing === 'undefined' ? false : options.tracing;
}

@@ -19,10 +24,18 @@ /**

Http.prototype.setupOnce = function () {
var nativeModule = require('module');
utils_1.fill(nativeModule, '_load', loadWrapper(nativeModule));
// observation: when the https module does its own require('http'), it *does not* hit our hooked require to instrument http on the fly
// but if we've previously instrumented http, https *does* get our already-instrumented version
// this is because raven's transports are required before this instrumentation takes place, which loads https (and http)
// so module cache will have uninstrumented http; proactively loading it here ensures instrumented version is in module cache
// alternatively we could refactor to load our transports later, but this is easier and doesn't have much drawback
require('http');
// No need to instrument if we don't want to track anything
if (!this._breadcrumbs && !this._tracing) {
return;
}
var handlerWrapper = createHandlerWrapper(this._breadcrumbs, this._tracing);
var httpModule = require('http');
utils_1.fill(httpModule, 'get', handlerWrapper);
utils_1.fill(httpModule, 'request', handlerWrapper);
// NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it.
// If we do, we'd get double breadcrumbs and double spans for `https` calls.
// It has been changed in Node 9, so for all versions equal and above, we patch `https` separately.
if (NODE_VERSION.major && NODE_VERSION.major > 8) {
var httpsModule = require('https');
utils_1.fill(httpsModule, 'get', handlerWrapper);
utils_1.fill(httpsModule, 'request', handlerWrapper);
}
};

@@ -37,2 +50,64 @@ /**

/**
* Wrapper function for internal `request` and `get` calls within `http` and `https` modules
*/
function createHandlerWrapper(breadcrumbsEnabled, tracingEnabled) {
return function handlerWrapper(originalHandler) {
return function (options) {
var requestUrl = extractUrl(options);
if (isSentryRequest(requestUrl)) {
return originalHandler.apply(this, arguments);
}
var span;
if (tracingEnabled) {
span = core_1.getCurrentHub().startSpan({
description: (typeof options === 'string' || !options.method ? 'GET' : options.method) + "|" + requestUrl,
op: 'request',
});
}
return originalHandler
.apply(this, arguments)
.once('response', function (res) {
if (breadcrumbsEnabled) {
addRequestBreadcrumb('response', requestUrl, this, res);
}
// TODO: Mark >= 500 as failed as well?
if (tracingEnabled) {
span.setSuccess();
span.finish();
}
})
.once('error', function () {
if (breadcrumbsEnabled) {
addRequestBreadcrumb('error', requestUrl, this);
}
if (tracingEnabled) {
span.setFailure();
span.finish();
}
});
};
};
}
/**
* Captures Breadcrumb based on provided request/response pair
*/
function addRequestBreadcrumb(event, url, req, res) {
if (!core_1.getCurrentHub().getIntegration(Http)) {
return;
}
core_1.getCurrentHub().addBreadcrumb({
category: 'http',
data: {
method: req.method,
status_code: res && res.statusCode,
url: url,
},
type: 'http',
}, {
event: event,
request: req,
response: res,
});
}
/**
* Function that can combine together a url that'll be used for our breadcrumbs.

@@ -43,6 +118,3 @@ *

*/
function createBreadcrumbUrl(options) {
// 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
function extractUrl(options) {
if (typeof options === 'string') {

@@ -59,87 +131,16 @@ return options;

/**
* Wrapper function for internal _load calls within `require`
* Checks whether given url points to Sentry server
* @param url url to verify
*/
function loadWrapper(nativeModule) {
// We need to use some functional-style currying to pass values around
// as we cannot rely on `bind`, because this has to preserve correct
// context for native calls
return function (originalLoad) {
return function (moduleId) {
var originalModule = originalLoad.apply(nativeModule, arguments);
if (moduleId !== 'http' || originalModule.__sentry__) {
return originalModule;
}
var origClientRequest = originalModule.ClientRequest;
var clientRequest = function (options, callback) {
// 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, callback);
this.__ravenBreadcrumbUrl = createBreadcrumbUrl(options);
};
util.inherits(clientRequest, origClientRequest);
utils_1.fill(clientRequest.prototype, 'emit', emitWrapper);
utils_1.fill(originalModule, 'ClientRequest', function () {
return clientRequest;
});
// 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_1.fill(originalModule, 'request', function () {
return function (options, callback) {
return new originalModule.ClientRequest(options, callback);
};
});
utils_1.fill(originalModule, 'get', function () {
return function (options, callback) {
var req = originalModule.request(options, callback);
req.end();
return req;
};
});
originalModule.__sentry__ = true;
return originalModule;
};
};
function isSentryRequest(url) {
var client = core_1.getCurrentHub().getClient();
if (!url || !client) {
return false;
}
var dsn = client.getDsn();
if (!dsn) {
return false;
}
return url.indexOf(dsn.host) !== -1;
}
/**
* Wrapper function for request's `emit` calls
*/
function emitWrapper(origEmit) {
return function (event, response) {
// I'm not sure why but Node.js (at least in v8.X)
// is emitting all events twice :|
if (lastResponse === undefined || lastResponse !== response) {
lastResponse = response;
}
else {
return origEmit.apply(this, arguments);
}
var client = core_1.getCurrentHub().getClient();
if (client) {
var dsn = client.getDsn();
var isInterestingEvent = event === 'response' || event === 'error';
var isNotSentryRequest = dsn && this.__ravenBreadcrumbUrl && this.__ravenBreadcrumbUrl.indexOf(dsn.host) === -1;
if (isInterestingEvent && isNotSentryRequest && core_1.getCurrentHub().getIntegration(Http)) {
core_1.getCurrentHub().addBreadcrumb({
category: 'http',
data: {
method: this.method,
status_code: response.statusCode,
url: this.__ravenBreadcrumbUrl,
},
type: 'http',
}, {
event: event,
request: this,
response: response,
});
}
}
return origEmit.apply(this, arguments);
};
}
//# sourceMappingURL=http.js.map
export declare const SDK_NAME = "sentry.javascript.node";
export declare const SDK_VERSION = "5.7.1";
export declare const SDK_VERSION = "5.8.0-beta.0";
//# sourceMappingURL=version.d.ts.map
Object.defineProperty(exports, "__esModule", { value: true });
exports.SDK_NAME = 'sentry.javascript.node';
exports.SDK_VERSION = '5.7.1';
exports.SDK_VERSION = '5.8.0-beta.0';
//# sourceMappingURL=version.js.map
/// <reference types="node" />
import { Event } from '@sentry/types';
import * as http from 'http';
/**
* Express compatible tracing handler.
* @see Exposed as `Handlers.tracingHandler`
*/
export declare function tracingHandler(): (req: http.IncomingMessage, res: http.ServerResponse, next: (error?: any) => void) => void;
declare type TransactionTypes = 'path' | 'methodPath' | 'handler';

@@ -5,0 +10,0 @@ /**

import * as tslib_1 from "tslib";
import { captureException, getCurrentHub, withScope } from '@sentry/core';
import { Span } from '@sentry/hub';
import { captureException, getCurrentHub, Span, withScope } from '@sentry/core';
import { forget, isString, logger, normalize } from '@sentry/utils';

@@ -11,2 +10,31 @@ import * as cookie from 'cookie';

var DEFAULT_SHUTDOWN_TIMEOUT = 2000;
/**
* Express compatible tracing handler.
* @see Exposed as `Handlers.tracingHandler`
*/
export function tracingHandler() {
return function sentryTracingMiddleware(req, res, next) {
// TODO: At this point req.route.path we use in `extractTransaction` is not available
// but `req.path` or `req.url` should do the job as well. We could unify this here.
var reqMethod = (req.method || '').toUpperCase();
var reqUrl = req.url;
var hub = getCurrentHub();
var transaction = hub.startSpan({
transaction: reqMethod + "|" + reqUrl,
});
hub.configureScope(function (scope) {
scope.setSpan(transaction);
});
res.once('finish', function () {
if (res.statusCode >= 500) {
transaction.setFailure();
}
else {
transaction.setSuccess();
}
transaction.finish();
});
next();
};
}
/** JSDoc */

@@ -210,12 +238,12 @@ function extractTransaction(req, type) {

export function errorHandler(options) {
return function sentryErrorMiddleware(error, _req, _res, next) {
return function sentryErrorMiddleware(error, req, res, next) {
var shouldHandleError = (options && options.shouldHandleError) || defaultShouldHandleError;
if (shouldHandleError(error)) {
withScope(function (scope) {
if (_req.headers && isString(_req.headers['sentry-trace'])) {
var span = Span.fromTraceparent(_req.headers['sentry-trace']);
if (req.headers && isString(req.headers['sentry-trace'])) {
var span = Span.fromTraceparent(req.headers['sentry-trace']);
scope.setSpan(span);
}
var eventId = captureException(error);
_res.sentry = eventId;
res.sentry = eventId;
next(error);

@@ -222,0 +250,0 @@ });

export { Breadcrumb, Request, SdkInfo, Event, Exception, Response, Severity, StackFrame, Stacktrace, Status, Thread, User, } from '@sentry/types';
export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, getCurrentHub, getHubFromCarrier, Hub, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, Span, withScope, } from '@sentry/core';
export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, getHubFromCarrier, getCurrentHub, Hub, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startSpan, Span, withScope, } from '@sentry/core';
export { NodeOptions } from './backend';

@@ -4,0 +4,0 @@ export { NodeClient } from './client';

import * as tslib_1 from "tslib";
export { Severity, Status, } from '@sentry/types';
export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, getCurrentHub, getHubFromCarrier, Hub, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, Span, withScope, } from '@sentry/core';
export { addGlobalEventProcessor, addBreadcrumb, captureException, captureEvent, captureMessage, configureScope, getHubFromCarrier, getCurrentHub, Hub, Scope, setContext, setExtra, setExtras, setTag, setTags, setUser, startSpan, Span, withScope, } from '@sentry/core';
export { NodeClient } from './client';

@@ -5,0 +5,0 @@ export { defaultIntegrations, init, lastEventId, flush, close } from './sdk';

@@ -18,6 +18,17 @@ import * as tslib_1 from "tslib";

Console.prototype.setupOnce = function () {
var nativeModule = require('module');
fill(nativeModule, '_load', loadWrapper(nativeModule));
// special case: since console is built-in and app-level code won't require() it, do that here
require('console');
var e_1, _a;
var consoleModule = require('console');
try {
for (var _b = tslib_1.__values(['debug', 'info', 'warn', 'error', 'log']), _c = _b.next(); !_c.done; _c = _b.next()) {
var level = _c.value;
fill(consoleModule, level, createConsoleWrapper(level));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};

@@ -32,62 +43,38 @@ /**

/**
* Wrapper function for internal _load calls within `require`
*/
function loadWrapper(nativeModule) {
// We need to use some functional-style currying to pass values around
// as we cannot rely on `bind`, because this has to preserve correct
// context for native calls
return function (originalLoad) {
return function (moduleId) {
var originalModule = originalLoad.apply(nativeModule, arguments);
if (moduleId !== 'console' || originalModule.__sentry__) {
return originalModule;
}
['debug', 'info', 'warn', 'error', 'log'].forEach(consoleWrapper(originalModule));
originalModule.__sentry__ = true;
return originalModule;
};
};
}
/**
* Wrapper function that'll be used for every console level
*/
function consoleWrapper(originalModule) {
return function (level) {
if (!(level in originalModule)) {
return;
function createConsoleWrapper(level) {
return function consoleWrapper(originalConsoleMethod) {
var sentryLevel;
switch (level) {
case 'debug':
sentryLevel = Severity.Debug;
break;
case 'error':
sentryLevel = Severity.Error;
break;
case 'info':
sentryLevel = Severity.Info;
break;
case 'warn':
sentryLevel = Severity.Warning;
break;
default:
sentryLevel = Severity.Log;
}
fill(originalModule, level, function (originalConsoleLevel) {
var sentryLevel;
switch (level) {
case 'debug':
sentryLevel = Severity.Debug;
break;
case 'error':
sentryLevel = Severity.Error;
break;
case 'info':
sentryLevel = Severity.Info;
break;
case 'warn':
sentryLevel = Severity.Warning;
break;
default:
sentryLevel = Severity.Log;
return function () {
if (getCurrentHub().getIntegration(Console)) {
getCurrentHub().addBreadcrumb({
category: 'console',
level: sentryLevel,
message: util.format.apply(undefined, arguments),
}, {
input: tslib_1.__spread(arguments),
level: level,
});
}
return function () {
if (getCurrentHub().getIntegration(Console)) {
getCurrentHub().addBreadcrumb({
category: 'console',
level: sentryLevel,
message: util.format.apply(undefined, arguments),
}, {
input: tslib_1.__spread(arguments),
level: level,
});
}
originalConsoleLevel.apply(originalModule, arguments);
};
});
originalConsoleMethod.apply(this, arguments);
};
};
}
//# sourceMappingURL=console.js.map

@@ -15,4 +15,19 @@ import { Integration } from '@sentry/types';

*/
private readonly _breadcrumbs;
/**
* @inheritDoc
*/
private readonly _tracing;
/**
* @inheritDoc
*/
constructor(options?: {
breadcrumbs?: boolean;
tracing?: boolean;
});
/**
* @inheritDoc
*/
setupOnce(): void;
}
//# sourceMappingURL=http.d.ts.map
import { getCurrentHub } from '@sentry/core';
import { fill } from '@sentry/utils';
import * as util from 'util';
var lastResponse;
import { fill, parseSemver } from '@sentry/utils';
var NODE_VERSION = parseSemver(process.versions.node);
/** http module integration */
var Http = /** @class */ (function () {
function Http() {
/**
* @inheritDoc
*/
function Http(options) {
if (options === void 0) { options = {}; }
/**

@@ -12,2 +15,4 @@ * @inheritDoc

this.name = Http.id;
this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;
this._tracing = typeof options.tracing === 'undefined' ? false : options.tracing;
}

@@ -18,10 +23,18 @@ /**

Http.prototype.setupOnce = function () {
var nativeModule = require('module');
fill(nativeModule, '_load', loadWrapper(nativeModule));
// observation: when the https module does its own require('http'), it *does not* hit our hooked require to instrument http on the fly
// but if we've previously instrumented http, https *does* get our already-instrumented version
// this is because raven's transports are required before this instrumentation takes place, which loads https (and http)
// so module cache will have uninstrumented http; proactively loading it here ensures instrumented version is in module cache
// alternatively we could refactor to load our transports later, but this is easier and doesn't have much drawback
require('http');
// No need to instrument if we don't want to track anything
if (!this._breadcrumbs && !this._tracing) {
return;
}
var handlerWrapper = createHandlerWrapper(this._breadcrumbs, this._tracing);
var httpModule = require('http');
fill(httpModule, 'get', handlerWrapper);
fill(httpModule, 'request', handlerWrapper);
// NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it.
// If we do, we'd get double breadcrumbs and double spans for `https` calls.
// It has been changed in Node 9, so for all versions equal and above, we patch `https` separately.
if (NODE_VERSION.major && NODE_VERSION.major > 8) {
var httpsModule = require('https');
fill(httpsModule, 'get', handlerWrapper);
fill(httpsModule, 'request', handlerWrapper);
}
};

@@ -36,2 +49,64 @@ /**

/**
* Wrapper function for internal `request` and `get` calls within `http` and `https` modules
*/
function createHandlerWrapper(breadcrumbsEnabled, tracingEnabled) {
return function handlerWrapper(originalHandler) {
return function (options) {
var requestUrl = extractUrl(options);
if (isSentryRequest(requestUrl)) {
return originalHandler.apply(this, arguments);
}
var span;
if (tracingEnabled) {
span = getCurrentHub().startSpan({
description: (typeof options === 'string' || !options.method ? 'GET' : options.method) + "|" + requestUrl,
op: 'request',
});
}
return originalHandler
.apply(this, arguments)
.once('response', function (res) {
if (breadcrumbsEnabled) {
addRequestBreadcrumb('response', requestUrl, this, res);
}
// TODO: Mark >= 500 as failed as well?
if (tracingEnabled) {
span.setSuccess();
span.finish();
}
})
.once('error', function () {
if (breadcrumbsEnabled) {
addRequestBreadcrumb('error', requestUrl, this);
}
if (tracingEnabled) {
span.setFailure();
span.finish();
}
});
};
};
}
/**
* Captures Breadcrumb based on provided request/response pair
*/
function addRequestBreadcrumb(event, url, req, res) {
if (!getCurrentHub().getIntegration(Http)) {
return;
}
getCurrentHub().addBreadcrumb({
category: 'http',
data: {
method: req.method,
status_code: res && res.statusCode,
url: url,
},
type: 'http',
}, {
event: event,
request: req,
response: res,
});
}
/**
* Function that can combine together a url that'll be used for our breadcrumbs.

@@ -42,6 +117,3 @@ *

*/
function createBreadcrumbUrl(options) {
// 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
function extractUrl(options) {
if (typeof options === 'string') {

@@ -58,87 +130,16 @@ return options;

/**
* Wrapper function for internal _load calls within `require`
* Checks whether given url points to Sentry server
* @param url url to verify
*/
function loadWrapper(nativeModule) {
// We need to use some functional-style currying to pass values around
// as we cannot rely on `bind`, because this has to preserve correct
// context for native calls
return function (originalLoad) {
return function (moduleId) {
var originalModule = originalLoad.apply(nativeModule, arguments);
if (moduleId !== 'http' || originalModule.__sentry__) {
return originalModule;
}
var origClientRequest = originalModule.ClientRequest;
var clientRequest = function (options, callback) {
// 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, callback);
this.__ravenBreadcrumbUrl = createBreadcrumbUrl(options);
};
util.inherits(clientRequest, origClientRequest);
fill(clientRequest.prototype, 'emit', emitWrapper);
fill(originalModule, 'ClientRequest', function () {
return clientRequest;
});
// 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
fill(originalModule, 'request', function () {
return function (options, callback) {
return new originalModule.ClientRequest(options, callback);
};
});
fill(originalModule, 'get', function () {
return function (options, callback) {
var req = originalModule.request(options, callback);
req.end();
return req;
};
});
originalModule.__sentry__ = true;
return originalModule;
};
};
function isSentryRequest(url) {
var client = getCurrentHub().getClient();
if (!url || !client) {
return false;
}
var dsn = client.getDsn();
if (!dsn) {
return false;
}
return url.indexOf(dsn.host) !== -1;
}
/**
* Wrapper function for request's `emit` calls
*/
function emitWrapper(origEmit) {
return function (event, response) {
// I'm not sure why but Node.js (at least in v8.X)
// is emitting all events twice :|
if (lastResponse === undefined || lastResponse !== response) {
lastResponse = response;
}
else {
return origEmit.apply(this, arguments);
}
var client = getCurrentHub().getClient();
if (client) {
var dsn = client.getDsn();
var isInterestingEvent = event === 'response' || event === 'error';
var isNotSentryRequest = dsn && this.__ravenBreadcrumbUrl && this.__ravenBreadcrumbUrl.indexOf(dsn.host) === -1;
if (isInterestingEvent && isNotSentryRequest && getCurrentHub().getIntegration(Http)) {
getCurrentHub().addBreadcrumb({
category: 'http',
data: {
method: this.method,
status_code: response.statusCode,
url: this.__ravenBreadcrumbUrl,
},
type: 'http',
}, {
event: event,
request: this,
response: response,
});
}
}
return origEmit.apply(this, arguments);
};
}
//# sourceMappingURL=http.js.map
export declare const SDK_NAME = "sentry.javascript.node";
export declare const SDK_VERSION = "5.7.1";
export declare const SDK_VERSION = "5.8.0-beta.0";
//# sourceMappingURL=version.d.ts.map
export var SDK_NAME = 'sentry.javascript.node';
export var SDK_VERSION = '5.7.1';
export var SDK_VERSION = '5.8.0-beta.0';
//# sourceMappingURL=version.js.map
{
"name": "@sentry/node",
"version": "5.7.1",
"version": "5.8.0-beta.0",
"description": "Offical Sentry SDK for Node.js",

@@ -19,13 +19,13 @@ "repository": "git://github.com/getsentry/sentry-javascript.git",

"dependencies": {
"@sentry/core": "5.7.1",
"@sentry/hub": "5.7.1",
"@sentry/types": "5.7.1",
"@sentry/utils": "5.7.1",
"cookie": "^0.3.1",
"https-proxy-agent": "^3.0.0",
"lru_map": "^0.3.3",
"@sentry/core": "5.8.0-beta.0",
"@sentry/hub": "5.8.0-beta.0",
"@sentry/types": "5.8.0-beta.0",
"@sentry/utils": "5.8.0-beta.0",
"cookie": "0.3.1",
"https-proxy-agent": "2.2.1",
"lru_map": "0.3.3",
"tslib": "^1.9.3"
},
"devDependencies": {
"@types/cookie": "^0.3.2",
"@types/cookie": "0.3.2",
"@types/lru-cache": "^5.1.0",

@@ -32,0 +32,0 @@ "@types/node": "^11.13.7",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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