8000 feat(core): Deprecate `hub.bindClient()` & `makeMain()` (#10188) · GingerAdonis/sentry-javascript@0cc2ac9 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 0cc2ac9

Browse files
authored
feat(core): Deprecate hub.bindClient() & makeMain() (getsentry#10188)
Instead, users should use `setCurrentClient()` & `client.init()`. For now, we can't fully replace our own test usages of this everywhere, as we need it to test a clean hub state. But for users, there should be a reasonable path forward for 99% of cases. I added a docs page outlining how the different scenarios will work in v8 (and already should work now, too).
1 parent b397b39 commit 0cc2ac9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+348
-187
lines changed

.size-limit.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ module.exports = [
7272
name: '@sentry/browser (incl. Tracing) - ES6 CDN Bundle (gzipped)',
7373
path: 'packages/browser/build/bundles/bundle.tracing.min.js',
7474
gzip: true,
75-
limit: '35 KB',
75+
limit: '37 KB',
7676
},
7777
{
7878
name: '@sentry/browser - ES6 CDN Bundle (gzipped)',
@@ -94,7 +94,7 @@ module.exports = [
9494
path: 'packages/browser/build/bundles/bundle.tracing.min.js',
9595
gzip: false,
9696
brotli: false,
97-
limit: '100 KB',
97+
limit: '105 KB',
9898
},
9999
{
100100
name: '@sentry/browser - ES6 CDN Bundle (minified & uncompressed)',

MIGRATION.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@ npx @sentry/migr8@latest
1010
This will let you select which updates to run, and automatically update your code. Make sure to still review all code
1111
changes!
1212

13-
## Deprecated `Transaction` integration
13+
## Deprecate `hub.bindClient()` and `makeMain()`
14+
15+
Instead, either directly use `initAndBind()`, or the new APIs `setCurrentClient()` and `client.init()`. See
16+
[Initializing the SDK in v8](./docs/v8-initializing.md) for more details.
17+
18+
## Deprecate `Transaction` integration
1419

1520
This pluggable integration from `@sentry/integrations` will be removed in v8. It was already undocumented and is not
1621
necessary for the SDK to work as expected.

docs/v8-initializing.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Initializing the SDK in v8
2+
3+
In v8, manual initialization of the SDK will work as follows.
4+
5+
## Classic initialization
6+
7+
```ts
8+
import * as Sentry from '@sentry/browser';
9+
10+
Sentry.init({
11+
dsn: 'xxx',
12+
});
13+
```
14+
15+
This will initialize the SDK with all defaults & make it the currently active Sentry instance. This will continue to use
16+
the existing global, isolation & current scope, and just bind the client to it.
17+
18+
## Using multiple clients in Node
19+
20+
In an environment with multiple execution contexts (e.g. Node), you can setup multiple clients that are active for
21+
different contexts, like this:
22+
23+
```js
24+
import * as Sentry from '@sentry/browser';
25+
26+
// Sets up the _default_ client
27+
Sentry.init({
28+
dsn: 'xxx',
29+
});
30+
31+
// One execution context with client A
32+
Sentry.withScope(() => {
33+
const clientA = new Client();
34+
Sentry.setCurrentClient(clientA); // binds this client to the current execution context only!
35+
clientA.init();
36+
});
37+
38+
// One execution context with client B
39+
Sentry.withScope(() => {
40+
const clientB = new Client();
41+
Sentry.setCurrentClient(clientB); // binds this client to the current execution context only!
42+
clientB.init();
43+
});
44+
```
45+
46+
## Using multiple clients in Browser
47+
48+
In environments without execution contexts, like the browser, you can only ever have a single active client. You can,
49+
however, create further clients and use them manually:
50+
51+
```js
52+
// Default client - this is used everywhere
53+
Sentry.init({
54+
dsn: 'xxx',
55+
});
56+
57+
// Setup a manual client
58+
const clientA = new Client();
59+
const scope = new Scope();
60+
scope.setClient(clientA);
61+
// You can capture exceptions manually for this client like this:
62+
scope.captureException();
63+
```
64+
65+
This is also necessary e.g. if you have a browser extension or some other code that runs in a shared environment.

packages/astro/src/index.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ export {
3131
getGlobalScope,
3232
getIsolationScope,
3333
Hub,
34+
// eslint-disable-next-line deprecation/deprecation
3435
makeMain,
36+
setCurrentClient,
3537
Scope,
3638
// eslint-disable-next-line deprecation/deprecation
3739
startTransaction,

packages/browser/src/exports.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ export {
4343
Hub,
4444
// eslint-disable-next-line deprecation/deprecation
4545
lastEventId,
46+
// eslint-disable-next-line deprecation/deprecation
47+
// eslint-disable-next-line deprecation/deprecation
4648
makeMain,
49+
setCurrentClient,
4750
Scope,
4851
// eslint-disable-next-line deprecation/deprecation
4952
startTransaction,

packages/browser/test/unit/index.test.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { WrappedFunction } from '@sentry/types';
33
import * as utils from '@sentry/utils';
44

55
import type { Event } from '../../src';
6+
import { setCurrentClient } from '../../src';
67
import {
78
BrowserClient,
89
Integrations,
@@ -14,7 +15,6 @@ import {
1415
captureMessage,
1516
flush,
1617
getClient,
17-
getCurrentHub,
1818
getCurrentScope,
1919
init,
2020
showReportDialog,
@@ -86,7 +86,7 @@ describe('SentryBrowser', () => {
8686
const client = new BrowserClient(options);
8787
it('uses the user on the scope', () => {
8888
getCurrentScope().setUser(EX_USER);
89-
getCurrentHub().bindClient(client);
89+
setCurrentClient(client);
9090

9191
// eslint-disable-next-line deprecation/deprecation
9292
showReportDialog();
@@ -100,7 +100,7 @@ describe('SentryBrowser', () => {
100100

101101
it('prioritizes options user over scope user', () => {
102102
getCurrentScope().setUser(EX_USER);
103-
getCurrentHub().bindClient(client);
103+
setCurrentClient(client);
104104

105105
const DIALOG_OPTION_USER = { email: 'option@example.com' };
106106
// eslint-disable-next-line deprecation/deprecation
@@ -216,7 +216,7 @@ describe('SentryBrowser', () => {
216216
},
217217
dsn,
218218
});
219-
getCurrentHub().bindClient(new BrowserClient(options));
219+
setCurrentClient(new BrowserClient(options));
220220
captureMessage('test');
221221
});
222222

@@ -230,7 +230,7 @@ describe('SentryBrowser', () => {
230230
},
231231
dsn,
232232
});
233-
getCurrentHub().bindClient(new BrowserClient(options));
233+
setCurrentClient(new BrowserClient(options));
234234
captureEvent({ message: 'event' });
235235
});
236236

@@ -243,7 +243,7 @@ describe('SentryBrowser', () => {
243243
},
244244
dsn,
245245
});
246-
getCurrentHub().bindClient(new BrowserClient(options));
246+
setCurrentClient(new BrowserClient(options));
247247
captureEvent({ message: 'event' });
248248
});
249249

@@ -254,7 +254,7 @@ describe('SentryBrowser', () => {
254254
dsn,
255255
integrations: [],
256256
});
257-
getCurrentHub().bindClient(new BrowserClient(options));
257+
setCurrentClient(new BrowserClient(options));
258258

259259
captureMessage('event222');
260260
captureMessage('event222');
@@ -271,7 +271,9 @@ describe('SentryBrowser', () => {
271271
dsn,
272272
integrations: [new Integrations.InboundFilters({ ignoreErrors: ['capture'] })],
273273
});
274-
getCurrentHub().bindClient(new BrowserClient(options));
274+
const client = new BrowserClient(options);
275+
setCurrentClient(client);
276+
client.init();
275277

276278
captureMessage('capture');
277279

@@ -405,7 +407,7 @@ describe('wrap()', () => {
405407
},
406408
dsn,
407409
});
408-
getCurrentHub().bindClient(new BrowserClient(options));
410+
setCurrentClient(new BrowserClient(options));
409411

410412
try {
411413
// eslint-disable-next-line deprecation/deprecation

packages/browser/test/unit/integrations/breadcrumbs.test.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,18 @@
11
import * as SentryCore from '@sentry/core';
2-
import type { Client } from '@sentry/types';
32

4-
import { Breadcrumbs, BrowserClient, Hub, flush } from '../../../src';
3+
import { Breadcrumbs, BrowserClient, flush } from '../../../src';
54
import { getDefaultBrowserClientOptions } from '../helper/browser-client-options';
65

7-
const hub = new Hub();
8-
let client: Client | undefined;
9-
10-
jest.mock('@sentry/core', () => {
11-
const original = jest.requireActual('@sentry/core');
12-
return {
13-
...original,
14-
getCurrentHub: () => hub,
15-
getClient: () => client,
16-
};
17-
});
18-
196
describe('Breadcrumbs', () => {
207
it('Should add sentry breadcrumb', async () => {
21-
client = new BrowserClient({
8+
const client = new BrowserClient({
229
...getDefaultBrowserClientOptions(),
2310
dsn: 'https://username@domain/123',
2411
integrations: [new Breadcrumbs()],
2512
});
2613

27-
SentryCore.getCurrentHub().bindClient(client);
14+
SentryCore.setCurrentClient(client);
15+
client.init();
2816

2917
const addBreadcrumbSpy = jest.spyOn(SentryCore, 'addBreadcrumb').mockImplementation(() => {});
3018

packages/browser/test/unit/profiling/hubextensions.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ describe('BrowserProfilingIntegration', () => {
4747
},
4848
};
4949

50+
// eslint-disable-next-line deprecation/deprecation
5051
hub.bindClient(client);
5152
});
5253

packages/bun/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export {
5050
Hub,
5151
// eslint-disable-next-line deprecation/deprecation
5252
lastEventId,
53+
// eslint-disable-next-line deprecation/deprecation
5354
makeMain,
55+
setCurrentClient,
5456
runWithAsyncContext,
5557
Scope,
5658
// eslint-disable-next-line deprecation/deprecation

packages/bun/test/integrations/bunserver.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ describe('Bun Serve Integration', () => {
2020
const options = getDefaultBunClientOptions({ tracesSampleRate: 1, debug: true });
2121
client = new BunClient(options);
2222
hub = new Hub(client);
23+
// eslint-disable-next-line deprecation/deprecation
2324
makeMain(hub);
2425
});
2526

packages/core/src/hub.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export class Hub implements HubInterface {
147147
this._stack = [{ scope: assignedScope }];
148148

149149
if (client) {
150+
// eslint-disable-next-line deprecation/deprecation
150151
this.bindClient(client);
151152
}
152153

@@ -166,7 +167,10 @@ export class Hub implements HubInterface {
166167
}
167168

168169
/**
169-
* @inheritDoc
170+
* This binds the given client to the current scope.
171+
* @param client An SDK client (client) instance.
172+
*
173+
* @deprecated Use `initAndBind()` directly, or `setCurrentClient()` and/or `client.init()` instead.
170174
*/
171175
public bindClient(client?: Client): void {
172176
// eslint-disable-next-line deprecation/deprecation
@@ -488,10 +492,12 @@ export class Hub implements HubInterface {
488492
* @inheritDoc
489493
*/
490494
public run(callback: (hub: Hub) => void): void {
495+
// eslint-disable-next-line deprecation/deprecation
491496
const oldHub = makeMain(this);
492497
try {
493498
callback(this);
494499
} finally {
500+
// eslint-disable-next-line deprecation/deprecation
495501
makeMain(oldHub);
496502
}
497503
}
@@ -690,6 +696,8 @@ export function getMainCarrier(): Carrier {
690696
* Replaces the current main hub with the passed one on the global object
691697
*
692698
* @returns The old replaced hub
699+
*
700+
* @deprecated Use `setCurrentClient()` instead.
693701
*/
694702
export function makeMain(hub: Hub): Hub {
695703
const registry = getMainCarrier();

packages/core/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export {
4141
getIsolationScope,
4242
getHubFromCarrier,
4343
Hub,
44+
// eslint-disable-next-line deprecation/deprecation
4445
makeMain,
4546
getMainCarrier,
4647
runWithAsyncContext,
@@ -59,7 +60,7 @@ export {
5960
export { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint } from './api';
6061
export { BaseClient, addEventProcessor } from './baseclient';
6162
export { ServerRuntimeClient } from './server-runtime-client';
62-
export { initAndBind } from './sdk';
63+
export { initAndBind, setCurrentClient } from './sdk';
6364
export { createTransport } from './transports/base';
6465
export { makeOfflineTransport } from './transports/offline';
6566
export { makeMultiplexedTransport } from './transports/multiplexed';

packages/core/src/sdk.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,32 @@ export function initAndBind<F extends Client, O extends ClientOptions>(
3535
scope.update(options.initialScope);
3636

3737
const client = new clientClass(options);
38-
hub.bindClient(client);
38+
setCurrentClient(client);
39+
initializeClient(client);
40+
}
41+
42+
/**
43+
* Make the given client the current client.
44+
*/
45+
export function setCurrentClient(client: Client): void {
46+
const hub = getCurrentHub();
47+
// eslint-disable-next-line deprecation/deprecation
48+
const top = hub.getStackTop();
49+
top.client = client;
50+
top.scope.setClient(client);
51+
}
52+
53+
/**
54+
* Initialize the client for the current scope.
55+
* Make sure to call this after `setCurrentClient()`.
56+
*/
57+
function initializeClient(client: Client): void {
58+
if (client.init) {
59+
client.init();
60+
// TODO v8: Remove this fallback
61+
// eslint-disable-next-line deprecation/deprecation
62+
} else if (client.setupIntegrations) {
63+
// eslint-disable-next-line deprecation/deprecation
64+
client.setupIntegrations();
65+
}
3966
}

packages/core/test/lib/exports.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe('withScope', () => {
3030
beforeEach(() => {
3131
const client = getTestClient();
3232
const hub = new Hub(client);
33+
// eslint-disable-next-line deprecation/deprecation
3334
makeMain(hub);
3435
});
3536

@@ -171,6 +172,7 @@ describe('session APIs', () => {
171172
beforeEach(() => {
172173
const client = getTestClient();
173174
const hub = new Hub(client);
175+
// eslint-disable-next-line deprecation/deprecation
174176
makeMain(hub);
175177
});
176178

packages/core/test/lib/integration.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ describe('addIntegration', () => {
618618

619619
const client = getTestClient();
620620
const hub = new Hub(client);
621+
// eslint-disable-next-line deprecation/deprecation
621622
makeMain(hub);
622623

623624
const integration = new CustomIntegration();
@@ -635,6 +636,7 @@ describe('addIntegration', () => {
635636
}
636637

637638
const hub = new Hub();
639+
// eslint-disable-next-line deprecation/deprecation
638640
makeMain(hub);
639641

640642
const integration = new CustomIntegration();

0 commit comments

Comments
 (0)
0