Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

meta: Update Changelog for 7.83.0 #9684

Merged
merged 12 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading