Skip to content

Commit

Permalink
Merge pull request #9684 from getsentry/prepare-release/7.83.0
Browse files Browse the repository at this point in the history
meta: Update Changelog for 7.83.0
  • Loading branch information
Lms24 authored Nov 28, 2023
2 parents f5ad00b + ab318e5 commit 85ff926
Show file tree
Hide file tree
Showing 178 changed files with 760 additions and 1,837 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 7.83.0

- chore(astro): Allow Astro 4.0 in peer dependencies (#9683)
- feat(astro): Add `assets` option to source maps upload options (#9668)
- feat(react): Support `exactOptionalPropertyTypes` on `ErrorBoundary` (#9098)
- fix: Don't depend on browser types in `types` (#9682)
- fix(astro): Configure sourcemap assets directory for Vercel adapter (#9665)
- fix(remix): Check the error data before spreading. (#9664)

## 7.82.0

- feat(astro): Automatically add Sentry middleware in Astro integration (#9532)
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Pro tip: If any of your breakpoints are in code run by multiple tests, and you r

## Debug Build Flags

Throughout the codebase, you will find the `__DEBUG_BUILD__` flag guarding various code sections. This flag serves two purposes:
Throughout the codebase, you will find a `__DEBUG_BUILD__` constant. This flag serves two purposes:

1. It enables us to remove debug code from our minified CDN bundles during build, by replacing the flag with `false` before tree-shaking occurs.
2. It enables users to remove Sentry debug code from their production bundles during their own build. When we build our npm packages, we replace the flag with `(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__)`. If the user does nothing, this evaluates to `true` and logging is included. But if the user runs their own replacement during build (again replacing the flag with `false`), the build will tree-shake the logging away, just as our bundle builds do.
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"access": "public"
},
"peerDependencies": {
"astro": "3.x"
"astro": ">=3.x"
},
"dependencies": {
"@sentry/browser": "7.82.0",
Expand Down
14 changes: 12 additions & 2 deletions packages/astro/src/integration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => {
authToken: uploadOptions.authToken ?? env.SENTRY_AUTH_TOKEN,
telemetry: uploadOptions.telemetry ?? true,
sourcemaps: {
assets: [getSourcemapsAssetsGlob(config)],
assets: uploadOptions.assets ?? [getSourcemapsAssetsGlob(config)],
},
debug: options.debug ?? false,
}),
Expand Down Expand Up @@ -100,9 +100,19 @@ function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
}

function getSourcemapsAssetsGlob(config: AstroConfig): string {
// The vercel adapter puts the output into its .vercel directory
// However, the way this adapter is written, the config.outDir value is update too late for
// us to reliably detect it. Also, server files are first temporarily written to <root>/dist and then
// only copied over to <root>/.vercel. This seems to happen too late though.
// So we glob on both of these directories.
// Another case of "it ain't pretty but it works":(
if (config.adapter?.name?.startsWith('@astrojs/vercel')) {
return '{.vercel,dist}/**/*';
}

// paths are stored as "file://" URLs
const outDirPathname = config.outDir && path.resolve(config.outDir.pathname);
const rootDirName = path.resolve((config.root && config.root.pathname) || process.cwd());
const rootDirName = path.resolve(config.root?.pathname || process.cwd());

if (outDirPathname) {
const relativePath = path.relative(rootDirName, outDirPathname);
Expand Down
12 changes: 12 additions & 0 deletions packages/astro/src/integration/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ type SourceMapsOptions = {
* @default true
*/
telemetry?: boolean;

/**
* A glob or an array of globs that specify the build artifacts and source maps that will uploaded to Sentry.
*
* If this option is not specified, sensible defaults based on your `outDir`, `rootDir` and `adapter`
* config will be used. Use this option to override these defaults, for instance if you have a
* customized build setup that diverges from Astro's defaults.
*
* The globbing patterns must follow the implementation of the `glob` package.
* @see https://www.npmjs.com/package/glob#glob-primer
*/
assets?: string | Array<string>;
};
};

Expand Down
59 changes: 59 additions & 0 deletions packages/astro/test/integration/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,65 @@ describe('sentryAstro integration', () => {
});
});

it('sets the correct assets glob for vercel if the Vercel adapter is used', async () => {
const integration = sentryAstro({
sourceMapsUploadOptions: { enabled: true, org: 'my-org', project: 'my-project', telemetry: false },
});
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({
updateConfig,
injectScript,
config: {
// @ts-expect-error - we only need to pass what we actually use
adapter: { name: '@astrojs/vercel/serverless' },
},
});

expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1);
expect(sentryVitePluginSpy).toHaveBeenCalledWith({
authToken: 'my-token',
org: 'my-org',
project: 'my-project',
telemetry: false,
debug: false,
sourcemaps: {
assets: ['{.vercel,dist}/**/*'],
},
});
});

it('prefers user-specified assets-globs over the default values', async () => {
const integration = sentryAstro({
sourceMapsUploadOptions: {
enabled: true,
org: 'my-org',
project: 'my-project',
assets: ['dist/server/**/*, dist/client/**/*'],
},
});
// @ts-expect-error - the hook exists and we only need to pass what we actually use
await integration.hooks['astro:config:setup']({
updateConfig,
injectScript,
// @ts-expect-error - only passing in partial config
config: {
outDir: new URL('file://path/to/project/build'),
},
});

expect(sentryVitePluginSpy).toHaveBeenCalledTimes(1);
expect(sentryVitePluginSpy).toHaveBeenCalledWith({
authToken: 'my-token',
org: 'my-org',
project: 'my-project',
telemetry: true,
debug: false,
sourcemaps: {
assets: ['dist/server/**/*, dist/client/**/*'],
},
});
});

it("doesn't enable source maps if `sourceMapsUploadOptions.enabled` is `false`", async () => {
const integration = sentryAstro({
sourceMapsUploadOptions: { enabled: false },
Expand Down
9 changes: 5 additions & 4 deletions packages/browser/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
} from '@sentry/types';
import { createClientReportEnvelope, dsnToString, getSDKSource, logger } from '@sentry/utils';

import { DEBUG_BUILD } from './debug-build';
import { eventFromException, eventFromMessage } from './eventbuilder';
import { WINDOW } from './helpers';
import type { BrowserTransportOptions } from './transports/types';
Expand Down Expand Up @@ -96,7 +97,7 @@ export class BrowserClient extends BaseClient<BrowserClientOptions> {
*/
public captureUserFeedback(feedback: UserFeedback): void {
if (!this._isEnabled()) {
__DEBUG_BUILD__ && logger.warn('SDK not enabled, will not capture user feedback.');
DEBUG_BUILD && logger.warn('SDK not enabled, will not capture user feedback.');
return;
}

Expand All @@ -123,17 +124,17 @@ export class BrowserClient extends BaseClient<BrowserClientOptions> {
const outcomes = this._clearOutcomes();

if (outcomes.length === 0) {
__DEBUG_BUILD__ && logger.log('No outcomes to send');
DEBUG_BUILD && logger.log('No outcomes to send');
return;
}

// This is really the only place where we want to check for a DSN and only send outcomes then
if (!this._dsn) {
__DEBUG_BUILD__ && logger.log('No dsn provided, will not send outcomes');
DEBUG_BUILD && logger.log('No dsn provided, will not send outcomes');
return;
}

__DEBUG_BUILD__ && logger.log('Sending outcomes:', outcomes);
DEBUG_BUILD && logger.log('Sending outcomes:', outcomes);

const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn));
void this._sendEnvelope(envelope);
Expand Down
8 changes: 8 additions & 0 deletions packages/browser/src/debug-build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare const __DEBUG_BUILD__: boolean;

/**
* This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
*
* ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
*/
export const DEBUG_BUILD = __DEBUG_BUILD__;
3 changes: 2 additions & 1 deletion packages/browser/src/integrations/breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
severityLevelFromString,
} from '@sentry/utils';

import { DEBUG_BUILD } from '../debug-build';
import { getClient } from '../exports';
import { WINDOW } from '../helpers';

Expand Down Expand Up @@ -148,7 +149,7 @@ function _domBreadcrumb(dom: BreadcrumbsOptions['dom']): (handlerData: HandlerDa
let maxStringLength =
typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;
if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {
__DEBUG_BUILD__ &&
DEBUG_BUILD &&
logger.warn(
`\`dom.maxStringLength\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,
);
Expand Down
4 changes: 3 additions & 1 deletion packages/browser/src/integrations/dedupe.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Event, Exception, Integration, StackFrame } from '@sentry/types';
import { logger } from '@sentry/utils';

import { DEBUG_BUILD } from '../debug-build';

/** Deduplication filter */
export class Dedupe implements Integration {
/**
Expand Down Expand Up @@ -40,7 +42,7 @@ export class Dedupe implements Integration {
// Juuust in case something goes wrong
try {
if (_shouldDropEvent(currentEvent, this._previousEvent)) {
__DEBUG_BUILD__ && logger.warn('Event dropped due to being a duplicate of previously captured event.');
DEBUG_BUILD && logger.warn('Event dropped due to being a duplicate of previously captured event.');
return null;
}
} catch (_oO) {} // eslint-disable-line no-empty
Expand Down
3 changes: 2 additions & 1 deletion packages/browser/src/integrations/globalhandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '@sentry/utils';

import type { BrowserClient } from '../client';
import { DEBUG_BUILD } from '../debug-build';
import { eventFromUnknownInput } from '../eventbuilder';
import { shouldIgnoreOnError } from '../helpers';

Expand Down Expand Up @@ -254,7 +255,7 @@ function _enhanceEventWithInitialFrame(event: Event, url: any, line: any, column
}

function globalHandlerLog(type: string): void {
__DEBUG_BUILD__ && logger.log(`Global Handler attached: ${type}`);
DEBUG_BUILD && logger.log(`Global Handler attached: ${type}`);
}

function getHubAndOptions(): [Hub, StackParser, boolean | undefined] {
Expand Down
15 changes: 8 additions & 7 deletions packages/browser/src/profiling/hubextensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { Transaction } from '@sentry/types';
import { logger, timestampInSeconds, uuid4 } from '@sentry/utils';

import { DEBUG_BUILD } from '../debug-build';
import { WINDOW } from '../helpers';
import type { JSSelfProfile } from './jsSelfProfiling';
import {
Expand All @@ -21,7 +22,7 @@ import {
*/
export function onProfilingStartRouteTransaction(transaction: Transaction | undefined): Transaction | undefined {
if (!transaction) {
if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log('[Profiling] Transaction is undefined, skipping profiling');
}
return transaction;
Expand Down Expand Up @@ -54,7 +55,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio
return transaction;
}

if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log(`[Profiling] started profiling transaction: ${transaction.name || transaction.description}`);
}

Expand Down Expand Up @@ -85,7 +86,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio
return null;
}
if (processedProfile) {
if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log(
'[Profiling] profile for:',
transaction.name || transaction.description,
Expand All @@ -103,13 +104,13 @@ export function startProfileForTransaction(transaction: Transaction): Transactio
maxDurationTimeoutID = undefined;
}

if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log(`[Profiling] stopped profiling of transaction: ${transaction.name || transaction.description}`);
}

// In case of an overlapping transaction, stopProfiling may return null and silently ignore the overlapping profile.
if (!profile) {
if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log(
`[Profiling] profiler returned null profile for: ${transaction.name || transaction.description}`,
'this may indicate an overlapping transaction or a call to stopProfiling with a profile title that was never started',
Expand All @@ -122,7 +123,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio
return null;
})
.catch(error => {
if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log('[Profiling] error while stopping profiler:', error);
}
return null;
Expand All @@ -131,7 +132,7 @@ export function startProfileForTransaction(transaction: Transaction): Transactio

// Enqueue a timeout to prevent profiles from running over max duration.
let maxDurationTimeoutID: number | undefined = WINDOW.setTimeout(() => {
if (__DEBUG_BUILD__) {
if (DEBUG_BUILD) {
logger.log(
'[Profiling] max profile duration elapsed, stopping profiling for:',
transaction.name || transaction.description,
Expand Down
9 changes: 4 additions & 5 deletions packages/browser/src/profiling/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { EventProcessor, Hub, Integration, Transaction } from '@sentry/type
import type { Profile } from '@sentry/types/src/profiling';
import { logger } from '@sentry/utils';

import { DEBUG_BUILD } from '../debug-build';
import { startProfileForTransaction } from './hubextensions';
import type { ProfiledEvent } from './utils';
import {
Expand Down Expand Up @@ -78,14 +79,12 @@ export class BrowserProfilingIntegration implements Integration {
const start_timestamp = context && context['profile'] && context['profile']['start_timestamp'];

if (typeof profile_id !== 'string') {
__DEBUG_BUILD__ &&
logger.log('[Profiling] cannot find profile for a transaction without a profile context');
DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a transaction without a profile context');
continue;
}

if (!profile_id) {
__DEBUG_BUILD__ &&
logger.log('[Profiling] cannot find profile for a transaction without a profile context');
DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a transaction without a profile context');
continue;
}

Expand All @@ -96,7 +95,7 @@ export class BrowserProfilingIntegration implements Integration {

const profile = takeProfileFromGlobalCache(profile_id);
if (!profile) {
__DEBUG_BUILD__ && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`);
DEBUG_BUILD && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`);
continue;
}

Expand Down
Loading

0 comments on commit 85ff926

Please sign in to comment.