Skip to content

Commit df253ad

Browse files
author
Luca Forstner
committed
fix: Wrap all console log instances in console sandbox
1 parent 97e04a0 commit df253ad

File tree

17 files changed

+110
-64
lines changed

17 files changed

+110
-64
lines changed

packages/core/src/hub.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,11 @@ export class Hub implements HubInterface {
377377
if (DEBUG_BUILD && !result) {
378378
const client = this.getClient();
379379
if (!client) {
380-
// eslint-disable-next-line no-console
381-
console.warn(
380+
logger.warn(
382381
"Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'",
383382
);
384383
} else {
385-
// eslint-disable-next-line no-console
386-
console.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
384+
logger.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
387385
Sentry.addTracingExtensions();
388386
Sentry.init({...});
389387
`);

packages/core/src/sdk.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Client, ClientOptions } from '@sentry/types';
2-
import { logger } from '@sentry/utils';
2+
import { consoleSandbox, logger } from '@sentry/utils';
33

44
import { DEBUG_BUILD } from './debug-build';
55
import { getCurrentHub } from './hub';
@@ -23,8 +23,10 @@ export function initAndBind<F extends Client, O extends ClientOptions>(
2323
logger.enable();
2424
} else {
2525
// use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped
26-
// eslint-disable-next-line no-console
27-
console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');
26+
consoleSandbox(() => {
27+
// eslint-disable-next-line no-console
28+
console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');
29+
});
2830
}
2931
}
3032
const hub = getCurrentHub();

packages/deno/src/transports/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createTransport } from '@sentry/core';
22
import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types';
3-
import { rejectedSyncPromise } from '@sentry/utils';
3+
import { consoleSandbox, rejectedSyncPromise } from '@sentry/utils';
44

55
export interface DenoTransportOptions extends BaseTransportOptions {
66
/** Custom headers for the transport. Used by the XHRTransport and FetchTransport */
@@ -14,9 +14,11 @@ export function makeFetchTransport(options: DenoTransportOptions): Transport {
1414
const url = new URL(options.url);
1515

1616
if (Deno.permissions.querySync({ name: 'net', host: url.host }).state !== 'granted') {
17-
// eslint-disable-next-line no-console
18-
console.warn(`Sentry SDK requires 'net' permission to send events.
19-
Run with '--allow-net=${url.host}' to grant the requires permissions.`);
17+
consoleSandbox(() => {
18+
// eslint-disable-next-line no-console
19+
console.warn(`Sentry SDK requires 'net' permission to send events.
20+
Run with '--allow-net=${url.host}' to grant the requires permissions.`);
21+
});
2022
}
2123

2224
function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {

packages/integration-shims/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"url": "https://github.com/getsentry/sentry-javascript/issues"
4444
},
4545
"dependencies": {
46-
"@sentry/types": "7.81.1"
46+
"@sentry/types": "7.81.1",
47+
"@sentry/utils": "7.81.1"
4748
},
4849
"engines": {
4950
"node": ">=12"

packages/integration-shims/src/BrowserTracing.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Integration } from '@sentry/types';
2+
import { consoleSandbox } from '@sentry/utils';
23

34
/**
45
* This is a shim for the BrowserTracing integration.
@@ -20,8 +21,10 @@ class BrowserTracingShim implements Integration {
2021
public constructor(_options: any) {
2122
this.name = BrowserTracingShim.id;
2223

23-
// eslint-disable-next-line no-console
24-
console.error('You are using new BrowserTracing() even though this bundle does not include tracing.');
24+
consoleSandbox(() => {
25+
// eslint-disable-next-line no-console
26+
console.error('You are using new BrowserTracing() even though this bundle does not include tracing.');
27+
});
2528
}
2629

2730
/** jsdoc */

packages/integration-shims/src/Replay.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Integration } from '@sentry/types';
2+
import { consoleSandbox } from '@sentry/utils';
23

34
/**
45
* This is a shim for the Replay integration.
@@ -20,8 +21,10 @@ class ReplayShim implements Integration {
2021
public constructor(_options: any) {
2122
this.name = ReplayShim.id;
2223

23-
// eslint-disable-next-line no-console
24-
console.error('You are using new Replay() even though this bundle does not include replay.');
24+
consoleSandbox(() => {
25+
// eslint-disable-next-line no-console
26+
console.error('You are using new Replay() even though this bundle does not include replay.');
27+
});
2528
}
2629

2730
/** jsdoc */

packages/nextjs/src/common/wrapApiHandlerWithSentry.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@ import {
66
startTransaction,
77
} from '@sentry/core';
88
import type { Transaction } from '@sentry/types';
9-
import { isString, logger, objectify, stripUrlQueryAndFragment, tracingContextFromHeaders } from '@sentry/utils';
9+
import {
10+
consoleSandbox,
11+
isString,
12+
logger,
13+
objectify,
14+
stripUrlQueryAndFragment,
15+
tracingContextFromHeaders,
16+
} from '@sentry/utils';
1017

1118
import { DEBUG_BUILD } from './debug-build';
1219
import type { AugmentedNextApiRequest, AugmentedNextApiResponse, NextApiHandler } from './types';
@@ -165,12 +172,14 @@ export function withSentry(apiHandler: NextApiHandler, parameterizedRoute?: stri
165172
// This can only happen (not always) when the user is using `withSentry` manually, which we're deprecating.
166173
// Warning suppression on Next.JS is only necessary in that case.
167174
) {
168-
// eslint-disable-next-line no-console
169-
console.warn(
170-
`[sentry] If Next.js logs a warning "API resolved without sending a response", it's a false positive, which may happen when you use \`withSentry\` manually to wrap your routes.
171-
To suppress this warning, set \`SENTRY_IGNORE_API_RESOLUTION_ERROR\` to 1 in your env.
172-
To suppress the nextjs warning, use the \`externalResolver\` API route option (see https://nextjs.org/docs/api-routes/api-middlewares#custom-config for details).`,
173-
);
175+
consoleSandbox(() => {
176+
// eslint-disable-next-line no-console
177+
console.warn(
178+
`[sentry] If Next.js logs a warning "API resolved without sending a response", it's a false positive, which may happen when you use \`withSentry\` manually to wrap your routes.
179+
To suppress this warning, set \`SENTRY_IGNORE_API_RESOLUTION_ERROR\` to 1 in your env.
180+
To suppress the nextjs warning, use the \`externalResolver\` API route option (see https://nextjs.org/docs/api-routes/api-middlewares#custom-config for details).`,
181+
);
182+
});
174183
}
175184

176185
return handlerResult;

packages/nextjs/src/config/webpack.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ class SentryCliDownloadPlugin implements WebpackPluginInstance {
10711071
if (!downloadingCliAttempted) {
10721072
downloadingCliAttempted = true;
10731073
// eslint-disable-next-line no-console
1074-
console.log(
1074+
logger.info(
10751075
`\n${chalk.cyan('info')} - ${chalk.bold(
10761076
'Sentry binary to upload source maps not found.',
10771077
)} Package manager post-install scripts are likely disabled or there is a caching issue. Manually downloading instead...`,
@@ -1087,12 +1087,12 @@ class SentryCliDownloadPlugin implements WebpackPluginInstance {
10871087
cliDownloadPromise.then(
10881088
() => {
10891089
// eslint-disable-next-line no-console
1090-
console.log(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`);
1090+
logger.info(`${chalk.cyan('info')} - Sentry binary was successfully downloaded.\n`);
10911091
return callback();
10921092
},
10931093
e => {
10941094
// eslint-disable-next-line no-console
1095-
console.error(`${chalk.red('error')} - Sentry binary download failed:`, e);
1095+
logger.error(`${chalk.red('error')} - Sentry binary download failed:`, e);
10961096
return callback();
10971097
},
10981098
);

packages/node/src/integrations/utils/errorhandling.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getClient } from '@sentry/core';
2-
import { logger } from '@sentry/utils';
2+
import { consoleSandbox, logger } from '@sentry/utils';
33

44
import type { NodeClient } from '../../client';
55
import { DEBUG_BUILD } from '../../debug-build';
@@ -10,8 +10,10 @@ const DEFAULT_SHUTDOWN_TIMEOUT = 2000;
1010
* @hidden
1111
*/
1212
export function logAndExitProcess(error: Error): void {
13-
// eslint-disable-next-line no-console
14-
console.error(error);
13+
consoleSandbox(() => {
14+
// eslint-disable-next-line no-console
15+
console.error(error);
16+
});
1517

1618
const client = getClient<NodeClient>();
1719

packages/node/src/transports/http.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
TransportRequest,
77
TransportRequestExecutor,
88
} from '@sentry/types';
9+
import { consoleSandbox } from '@sentry/utils';
910
import * as http from 'http';
1011
import * as https from 'https';
1112
import { HttpsProxyAgent } from 'https-proxy-agent';
@@ -53,10 +54,12 @@ export function makeNodeTransport(options: NodeTransportOptions): Transport {
5354
try {
5455
urlSegments = new URL(options.url);
5556
} catch (e) {
56-
// eslint-disable-next-line no-console
57-
console.warn(
58-
'[@sentry/node]: Invalid dsn or tunnel option, will not send any events. The tunnel option must be a full URL when used.',
59-
);
57+
consoleSandbox(() => {
58+
// eslint-disable-next-line no-console
59+
console.warn(
60+
'[@sentry/node]: Invalid dsn or tunnel option, will not send any events. The tunnel option must be a full URL when used.',
61+
);
62+
});
6063
return createTransport(options, () => Promise.resolve({}));
6164
}
6265

packages/opentelemetry/src/custom/hubextensions.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { addTracingExtensions as _addTracingExtensions, getMainCarrier } from '@sentry/core';
22
import type { CustomSamplingContext, TransactionContext } from '@sentry/types';
3+
import { consoleSandbox } from '@sentry/utils';
34

45
/**
56
* Add tracing extensions, ensuring a patched `startTransaction` to work with OTEL.
@@ -22,8 +23,10 @@ function startTransactionNoop(
2223
_transactionContext: TransactionContext,
2324
_customSamplingContext?: CustomSamplingContext,
2425
): unknown {
25-
// eslint-disable-next-line no-console
26-
console.warn('startTransaction is a noop in @sentry/opentelemetry. Use `startSpan` instead.');
26+
consoleSandbox(() => {
27+
// eslint-disable-next-line no-console
28+
console.warn('startTransaction is a noop in @sentry/opentelemetry. Use `startSpan` instead.');
29+
});
2730
// We return an object here as hub.ts checks for the result of this
2831
// and renders a different warning if this is empty
2932
return {};

packages/replay/src/integration.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getClient } from '@sentry/core';
22
import type { BrowserClientReplayOptions, Integration } from '@sentry/types';
3-
import { dropUndefinedKeys, isBrowser } from '@sentry/utils';
3+
import { consoleSandbox, dropUndefinedKeys, isBrowser } from '@sentry/utils';
44

55
import {
66
DEFAULT_FLUSH_MAX_DELAY,
@@ -349,8 +349,10 @@ function loadReplayOptionsFromClient(initialOptions: InitialReplayPluginOptions)
349349
const finalOptions = { sessionSampleRate: 0, errorSampleRate: 0, ...dropUndefinedKeys(initialOptions) };
350350

351351
if (!opt) {
352-
// eslint-disable-next-line no-console
353-
console.warn('SDK client is not available.');
352+
consoleSandbox(() => {
353+
// eslint-disable-next-line no-console
354+
console.warn('SDK client is not available.');
355+
});
354356
return finalOptions;
355357
}
356358

@@ -360,10 +362,12 @@ function loadReplayOptionsFromClient(initialOptions: InitialReplayPluginOptions)
360362
opt.replaysSessionSampleRate == null &&
361363
opt.replaysOnErrorSampleRate == null
362364
) {
363-
// eslint-disable-next-line no-console
364-
console.warn(
365-
'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.',
366-
);
365+
consoleSandbox(() => {
366+
// eslint-disable-next-line no-console
367+
console.warn(
368+
'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.',
369+
);
370+
});
367371
}
368372

369373
if (typeof opt.replaysSessionSampleRate === 'number') {

packages/replay/src/util/getPrivacyOptions.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { consoleSandbox } from '@sentry/utils';
2+
13
import type { DeprecatedPrivacyOptions, ReplayIntegrationPrivacyOptions } from '../types';
24

35
type GetPrivacyOptions = Required<Omit<ReplayIntegrationPrivacyOptions, 'maskFn'>> &
@@ -37,10 +39,12 @@ function getOption(
3739
allSelectors.push(`.${deprecatedClassOption}`);
3840
}
3941

40-
// eslint-disable-next-line no-console
41-
console.warn(
42-
'[Replay] You are using a deprecated configuration item for privacy. Read the documentation on how to use the new privacy configuration.',
43-
);
42+
consoleSandbox(() => {
43+
// eslint-disable-next-line no-console
44+
console.warn(
45+
'[Replay] You are using a deprecated configuration item for privacy. Read the documentation on how to use the new privacy configuration.',
46+
);
47+
});
4448
}
4549

4650
return allSelectors.join(',');

packages/sveltekit/src/client/handleError.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { captureException } from '@sentry/svelte';
2+
import { consoleSandbox } from '@sentry/utils';
23
// For now disable the import/no-unresolved rule, because we don't have a way to
34
// tell eslint that we are only importing types from the @sveltejs/kit package without
45
// adding a custom resolver, which will take too much time.
@@ -8,8 +9,10 @@ import type { HandleClientError, NavigationEvent } from '@sveltejs/kit';
89
// The SvelteKit default error handler just logs the error to the console
910
// see: https://github.com/sveltejs/kit/blob/369e7d6851f543a40c947e033bfc4a9506fdc0a8/packages/kit/src/core/sync/write_client_manifest.js#LL127C2-L127C2
1011
function defaultErrorHandler({ error }: Parameters<HandleClientError>[0]): ReturnType<HandleClientError> {
11-
// eslint-disable-next-line no-console
12-
console.error(error);
12+
consoleSandbox(() => {
13+
// eslint-disable-next-line no-console
14+
console.error(error);
15+
});
1316
}
1417

1518
/**

packages/utils/src/dsn.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { DsnComponents, DsnLike, DsnProtocol } from '@sentry/types';
22

33
import { DEBUG_BUILD } from './debug-build';
4-
import { logger } from './logger';
4+
import { consoleSandbox, logger } from './logger';
55

66
/** Regular expression used to parse a Dsn. */
77
const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)([\w.-]+)(?::(\d+))?\/(.+)/;
@@ -38,8 +38,10 @@ export function dsnFromString(str: string): DsnComponents | undefined {
3838

3939
if (!match) {
4040
// This should be logged to the console
41-
// eslint-disable-next-line no-console
42-
console.error(`Invalid Sentry Dsn: ${str}`);
41+
consoleSandbox(() => {
42+
// eslint-disable-next-line no-console
43+
console.error(`Invalid Sentry Dsn: ${str}`);
44+
});
4345
return undefined;
4446
}
4547

packages/vue/src/errorhandler.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getCurrentHub } from '@sentry/browser';
2+
import { consoleSandbox } from '@sentry/utils';
23

34
import type { ViewModel, Vue, VueOptions } from './types';
45
import { formatComponentName, generateComponentTrace } from './vendor/components';
@@ -46,8 +47,10 @@ export const attachErrorHandler = (app: Vue, options: VueOptions): void => {
4647
if (warnHandler) {
4748
(warnHandler as UnknownFunc).call(null, message, vm, trace);
4849
} else if (hasConsole && !silent) {
49-
// eslint-disable-next-line no-console
50-
console.error(`[Vue warn]: ${message}${trace}`);
50+
consoleSandbox(() => {
51+
// eslint-disable-next-line no-console
52+
console.error(`[Vue warn]: ${message}${trace}`);
53+
});
5154
}
5255
}
5356
};

packages/vue/src/integration.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { hasTracingEnabled } from '@sentry/core';
22
import type { Hub, Integration } from '@sentry/types';
3-
import { arrayify, GLOBAL_OBJ } from '@sentry/utils';
3+
import { arrayify, consoleSandbox, GLOBAL_OBJ } from '@sentry/utils';
44

55
import { DEFAULT_HOOKS } from './constants';
66
import { attachErrorHandler } from './errorhandler';
@@ -50,12 +50,14 @@ export class VueIntegration implements Integration {
5050
const options: Options = { ...DEFAULT_CONFIG, ...(client && client.getOptions()), ...this._options };
5151

5252
if (!options.Vue && !options.app) {
53-
// eslint-disable-next-line no-console
54-
console.warn(
55-
`[@sentry/vue]: Misconfigured SDK. Vue specific errors will not be captured.
56-
Update your \`Sentry.init\` call with an appropriate config option:
57-
\`app\` (Application Instance - Vue 3) or \`Vue\` (Vue Constructor - Vue 2).`,
58-
);
53+
consoleSandbox(() => {
54+
// eslint-disable-next-line no-console
55+
console.warn(
56+
`[@sentry/vue]: Misconfigured SDK. Vue specific errors will not be captured.
57+
Update your \`Sentry.init\` call with an appropriate config option:
58+
\`app\` (Application Instance - Vue 3) or \`Vue\` (Vue Constructor - Vue 2).`,
59+
);
60+
});
5961
return;
6062
}
6163

@@ -80,10 +82,12 @@ const vueInit = (app: Vue, options: Options): void => {
8082

8183
const isMounted = appWithInstance._instance && appWithInstance._instance.isMounted;
8284
if (isMounted === true) {
83-
// eslint-disable-next-line no-console
84-
console.warn(
85-
'[@sentry/vue]: Misconfigured SDK. Vue app is already mounted. Make sure to call `app.mount()` after `Sentry.init()`.',
86-
);
85+
consoleSandbox(() => {
86+
// eslint-disable-next-line no-console
87+
console.warn(
88+
'[@sentry/vue]: Misconfigured SDK. Vue app is already mounted. Make sure to call `app.mount()` after `Sentry.init()`.',
89+
);
90+
});
8791
}
8892

8993
attachErrorHandler(app, options);

0 commit comments

Comments
 (0)