Skip to content

Commit 06f3ff3

Browse files
authored
fix: Hub domain handling and requestHandler/errorHandler updates
1 parent 92c37f5 commit 06f3ff3

File tree

18 files changed

+577
-150
lines changed

18 files changed

+577
-150
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@
2424
- [core] ref: Remove Repo interface and repos attribute from Event
2525
- [core] ref: Rewrite RequestBuffer using Array instead of Set for IE10/11
2626
- [hub] fix: Scope level overwrites level on the event
27+
- [hub] fix: Correctly store and retrieve Hub from domain when one is active
28+
- [hub] fix: Copy over user data when cloning scope
2729
- [node] feat: Allow requestHandler to be configured
28-
- [node] feat: Make node transactions a pluggable integration with tests
30+
- [node] feat: Make node transactions a pluggable integration with tests
2931
- [node] feat: Transactions handling for RequestHandler in Express/Hapi
3032
- [node] fix: Dont wrap native modules more than once to prevent leaks
33+
- [node] fix: Use getCurrentHub to retrieve correct hub in requestHandler
34+
3135
- [utils] ref: implemented includes, assign and isNaN polyfills
3236

3337
## 4.0.6

packages/browser/rollup.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import builtins from 'rollup-plugin-node-builtins';
21
import commonjs from 'rollup-plugin-commonjs';
32
import uglify from 'rollup-plugin-uglify';
43
import resolve from 'rollup-plugin-node-resolve';
54
import typescript from 'rollup-plugin-typescript2';
65
import license from 'rollup-plugin-license';
6+
import builtins from 'rollup-plugin-node-builtins';
77

88
const commitHash = require('child_process')
99
.execSync('git rev-parse --short HEAD', { encoding: 'utf-8' })

packages/core/test/integrations/rewriteframes.test.ts renamed to packages/core/test/lib/integrations/rewriteframes.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SentryEvent, StackFrame } from '@sentry/types';
2-
import { RewriteFrames } from '../../src/integrations/pluggable/rewriteframes';
2+
import { RewriteFrames } from '../../../src/integrations/pluggable/rewriteframes';
33

44
let rewriteFrames: RewriteFrames;
55
let messageEvent: SentryEvent;

packages/hub/src/hub.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ export function makeMain(hub?: Hub): Hub | undefined {
287287
return oldHub;
288288
}
289289

290+
/** Domain interface with attached Hub */
291+
interface SentryDomain extends NodeJS.Domain {
292+
__SENTRY__?: Carrier;
293+
}
294+
290295
/**
291296
* Returns the default hub instance.
292297
*
@@ -301,7 +306,28 @@ export function getCurrentHub(): Hub {
301306
registry.hub = new Hub();
302307
}
303308

304-
return registry.hub;
309+
let domain = null;
310+
try {
311+
domain = process.domain as SentryDomain;
312+
} catch (_Oo) {
313+
// We do not have process
314+
}
315+
316+
if (!domain) {
317+
return registry.hub;
318+
}
319+
320+
let carrier = domain.__SENTRY__;
321+
if (!carrier) {
322+
domain.__SENTRY__ = carrier = {};
323+
}
324+
325+
if (!carrier.hub) {
326+
const top = registry.hub.getStackTop();
327+
carrier.hub = top ? new Hub(top.client, Scope.clone(top.scope)) : new Hub();
328+
}
329+
330+
return carrier.hub;
305331
}
306332

307333
/**

packages/hub/src/scope.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ export class Scope {
139139
scopeListeners: [],
140140
});
141141
if (scope) {
142+
newScope.extra = assign(scope.extra);
143+
newScope.tags = assign(scope.tags) as any;
144+
newScope.breadcrumbs = [...scope.breadcrumbs];
142145
newScope.eventProcessors = [...scope.eventProcessors];
143146
}
144147
return newScope;

packages/node/src/handlers.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { logger } from '@sentry/core';
2-
import { getHubFromCarrier, Scope } from '@sentry/hub';
2+
import { getCurrentHub, Scope } from '@sentry/hub';
33
import { SentryEvent, Severity } from '@sentry/types';
44
import { forget } from '@sentry/utils/async';
55
import { serialize } from '@sentry/utils/object';
@@ -9,7 +9,6 @@ import * as http from 'http';
99
import * as os from 'os';
1010
import * as url from 'url';
1111
import { NodeClient } from './client';
12-
import { getCurrentHub } from './hub';
1312

1413
const DEFAULT_SHUTDOWN_TIMEOUT = 2000;
1514

@@ -208,20 +207,22 @@ export function requestHandler(options?: {
208207
transaction?: boolean | TransactionTypes;
209208
user?: boolean;
210209
version?: boolean;
211-
}): (req: http.IncomingMessage, res: http.ServerResponse, next: () => void) => void {
210+
}): (req: http.IncomingMessage, res: http.ServerResponse, next: (error?: any) => void) => void {
212211
return function sentryRequestMiddleware(
213212
req: http.IncomingMessage,
214-
_res: http.ServerResponse,
215-
next: () => void,
213+
res: http.ServerResponse,
214+
next: (error?: any) => void,
216215
): void {
217216
const local = domain.create();
218-
const hub = getHubFromCarrier(req);
219-
hub.bindClient(getCurrentHub().getClient());
220-
hub.configureScope((scope: Scope) => {
221-
scope.addEventProcessor(async (event: SentryEvent) => parseRequest(event, req, options));
222-
});
217+
local.add(req);
218+
local.add(res);
223219
local.on('error', next);
224-
local.run(next);
220+
local.run(() => {
221+
getCurrentHub().configureScope(scope =>
222+
scope.addEventProcessor(async (event: SentryEvent) => parseRequest(event, req, options)),
223+
);
224+
next();
225+
});
225226
};
226227
}
227228

@@ -238,7 +239,6 @@ interface MiddlewareError extends Error {
238239
/** JSDoc */
239240
function getStatusCodeFromResponse(error: MiddlewareError): number {
240241
const statusCode = error.status || error.statusCode || error.status_code || (error.output && error.output.statusCode);
241-
242242
return statusCode ? parseInt(statusCode as string, 10) : 500;
243243
}
244244

@@ -251,7 +251,7 @@ export function errorHandler(): (
251251
) => void {
252252
return function sentryErrorMiddleware(
253253
error: MiddlewareError,
254-
req: http.IncomingMessage,
254+
_req: http.IncomingMessage,
255255
_res: http.ServerResponse,
256256
next: (error: MiddlewareError) => void,
257257
): void {
@@ -260,7 +260,7 @@ export function errorHandler(): (
260260
next(error);
261261
return;
262262
}
263-
getHubFromCarrier(req).captureException(error, { originalException: error });
263+
getCurrentHub().captureException(error, { originalException: error });
264264
next(error);
265265
};
266266
}

packages/node/src/hub.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

packages/node/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ export {
1919
captureEvent,
2020
captureMessage,
2121
configureScope,
22+
getCurrentHub,
2223
getHubFromCarrier,
2324
Hub,
2425
Scope,
2526
withScope,
2627
} from '@sentry/core';
2728

28-
export { getCurrentHub } from './hub';
2929
export { NodeBackend, NodeOptions } from './backend';
3030
export { NodeClient } from './client';
3131
export { defaultIntegrations, init } from './sdk';

packages/node/src/integrations/console.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import { getCurrentHub } from '@sentry/hub';
12
import { Integration, Severity } from '@sentry/types';
23
import { fill } from '@sentry/utils/object';
34
import * as util from 'util';
4-
import { getCurrentHub } from '../hub';
55

66
/**
77
* Wrapper function for internal _load calls within `require`

packages/node/src/integrations/http.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import { getCurrentHub } from '@sentry/hub';
12
import { Integration } from '@sentry/types';
23
import { fill } from '@sentry/utils/object';
34
import * as http from 'http';
45
import * as util from 'util';
5-
import { getCurrentHub } from '../hub';
66

77
let lastResponse: http.ServerResponse | undefined;
88

packages/node/src/integrations/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export { OnUnhandledRejection } from './onunhandledrejection';
55
export { LinkedErrors } from './linkederrors';
66

77
export { Modules } from './pluggable/modules';
8+
export { Transaction } from './pluggable/transaction';

packages/node/src/integrations/linkederrors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { getCurrentHub } from '@sentry/hub';
12
import { Integration, SentryEvent, SentryEventHint, SentryException } from '@sentry/types';
2-
import { getCurrentHub } from '../hub';
33
import { getExceptionFromError } from '../parsers';
44

55
const DEFAULT_KEY = 'cause';

packages/node/src/integrations/onunhandledrejection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { getCurrentHub } from '@sentry/hub';
12
import { Integration } from '@sentry/types';
2-
import { getCurrentHub } from '../hub';
33

44
/** Global Promise Rejection handler */
55
export class OnUnhandledRejection implements Integration {

packages/node/src/integrations/pluggable/modules.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { Scope } from '@sentry/hub';
1+
import { getCurrentHub, Scope } from '@sentry/hub';
22
import { Integration } from '@sentry/types';
33
import * as lsmod from 'lsmod';
44
import { NodeOptions } from '../../backend';
5-
import { getCurrentHub } from '../../hub';
65

76
let moduleCache: { [key: string]: string };
87

packages/node/src/integrations/pluggable/transaction.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { Scope } from '@sentry/hub';
1+
import { getCurrentHub, Scope } from '@sentry/hub';
22
import { Integration, SentryEvent, StackFrame } from '@sentry/types';
33
import { NodeOptions } from '../../backend';
4-
import { getCurrentHub } from '../../hub';
54

65
/** Add node transaction to the event */
76
export class Transaction implements Integration {

packages/node/test/domain.test.ts

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,7 @@
1-
import { Layer } from '@sentry/hub';
1+
import { getCurrentHub, Hub } from '@sentry/hub';
22
import * as domain from 'domain';
33

4-
const mockgetCurrentHub = jest.fn();
5-
6-
class MockHub {
7-
public constructor(public stack: Layer[] = []) {
8-
MockHub.instance = this;
9-
}
10-
public static instance: MockHub;
11-
12-
public getStack(): Layer[] {
13-
return this.stack;
14-
}
15-
16-
public getStackTop(): Layer {
17-
return this.stack[this.stack.length - 1];
18-
}
19-
}
20-
21-
const mockHub = MockHub;
22-
jest.mock('@sentry/hub', () => ({
23-
Hub: mockHub,
24-
getCurrentHub: mockgetCurrentHub,
25-
}));
26-
27-
import { getCurrentHub } from '../src';
28-
294
describe('domains', () => {
30-
let globalHub: MockHub;
31-
32-
beforeEach(() => {
33-
globalHub = new MockHub();
34-
mockgetCurrentHub.mockReturnValue(globalHub);
35-
});
36-
375
afterEach(() => {
386
if (domain.active) {
397
domain.active.exit();
@@ -44,26 +12,20 @@ describe('domains', () => {
4412
test('without domain', () => {
4513
expect(domain.active).toBeFalsy();
4614
const hub = getCurrentHub();
47-
expect(hub).toBe(globalHub);
15+
expect(hub).toEqual(new Hub());
4816
});
4917

50-
test('domain hub inheritance', () => {
51-
globalHub.stack = [];
52-
const d = domain.create();
53-
d.run(() => {
54-
const hub = getCurrentHub();
55-
expect(globalHub).not.toBe(hub);
56-
expect(globalHub.getStack()).toEqual(hub.getStack());
18+
test('domain hub scope inheritance', () => {
19+
const globalHub = getCurrentHub();
20+
globalHub.configureScope(scope => {
21+
scope.setExtra('a', 'b');
22+
scope.setTag('a', 'b');
23+
scope.addBreadcrumb({ message: 'a' });
5724
});
58-
});
59-
60-
test('domain hub isolation', () => {
6125
const d = domain.create();
6226
d.run(() => {
6327
const hub = getCurrentHub();
64-
hub.getStack().push({ client: 'whatever' });
65-
expect(hub.getStack()).toEqual([{ client: 'whatever' }]);
66-
expect(globalHub.getStack()).toEqual([]);
28+
expect(globalHub).toEqual(hub);
6729
});
6830
});
6931

@@ -84,7 +46,7 @@ describe('domains', () => {
8446
.push({ client: 'process' });
8547

8648
setTimeout(() => {
87-
expect(getCurrentHub().getStack()).toEqual([{ client: 'process' }]);
49+
expect(getCurrentHub().getStack()[1]).toEqual({ client: 'process' });
8850
}, 50);
8951
});
9052

@@ -94,7 +56,7 @@ describe('domains', () => {
9456
.push({ client: 'local' });
9557

9658
setTimeout(() => {
97-
expect(getCurrentHub().getStack()).toEqual([{ client: 'local' }]);
59+
expect(getCurrentHub().getStack()[1]).toEqual({ client: 'local' });
9860
done();
9961
}, 100);
10062
});

packages/utils/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"scripts": {
2929
"build": "run-s clean; tsc -p tsconfig.build.json",
30-
"build:watch": "run-s clean; tsc -p tsconfig.build.json -w --preserveWatchOutput",
30+
"build:watch": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
3131
"clean": "rimraf dist coverage *.js *.js.map *.d.ts",
3232
"lint": "run-s lint:prettier lint:tslint",
3333
"lint:prettier": "prettier-check '{src,test}/**/*.ts'",

0 commit comments

Comments
 (0)