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(changelog): Update changelog for 7.86.0 #9771

Merged
merged 13 commits into from
Dec 7, 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
3 changes: 1 addition & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -976,8 +976,7 @@ jobs:
runs-on: ubuntu-20.04
timeout-minutes: 30
if: |
contains(github.event.pull_request.labels.*.name, 'ci-overhead-measurements') ||
needs.job_get_metadata.outputs.is_develop == 'true'
contains(github.event.pull_request.labels.*.name, 'ci-overhead-measurements')
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v4
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@

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

## 7.86.0

- feat(core): Use SDK_VERSION for hub API version (#9732)
- feat(nextjs): Emit warning if your app directory doesn't have a global-error.js file (#9753)
- feat(node): Add cloudflare pages commit sha (#9751)
- feat(remix): Bump @sentry/cli to 2.22.3 (#9741)
- fix(nextjs): Don't accidentally trigger static generation bailout (#9749)
- fix(node): Guard `process.env.NODE_ENV` access in Spotlight integration (#9748)
- fix(utils): Fix XHR instrumentation early return (#9770)
- ref(remix): Rework Error Handling (#9725)

## 7.85.0

- feat(core): Add `addEventProcessor` method (#9554)
Expand Down
2 changes: 1 addition & 1 deletion docs/using-yalc.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ to add the local SDK package to your project.

### My changes are not applied to the test project

Did you run `yarn build && yarn publish:yalc` after making your changes?
Did you run `yarn build && yarn yalc:publish` after making your changes?

### My test project uses Vite and I still don't see changes

Expand Down
8 changes: 4 additions & 4 deletions packages/astro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

- [Official SDK Docs](https://docs.sentry.io/platforms/javascript/guides/astro/)

## Experimental Note
## SDK Status

This SDK is experimental and in Alpha state. Breaking changes can occurr at any time.
This SDK is in Beta and not yet fully stable.
If you have feedback or encounter any bugs, feel free to [open an issue](https://github.com/getsentry/sentry-javascript/issues/new/choose).

## General
Expand Down Expand Up @@ -58,9 +58,9 @@ SENTRY_AUTH_TOKEN="your-token"

### Server Instrumentation

For Astro apps configured for (hybrid) Server Side Rendering (SSR), the Sentry integration will automatically add middleware to your server to instrument incoming requests **if you're using Astro 3.5.0 or newer**.
For Astro apps configured for (hybrid) Server Side Rendering (SSR), the Sentry integration will automatically add middleware to your server to instrument incoming requests **if you're using Astro 3.5.2 or newer**.

If you're using Astro <3.5.0, complete the setup by adding the Sentry middleware to your `src/middleware.js` file:
If you're using Astro <3.5.2, complete the setup by adding the Sentry middleware to your `src/middleware.js` file:

```javascript
// src/middleware.js
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { DEFAULT_ENVIRONMENT } from './constants';
import { DEBUG_BUILD } from './debug-build';
import { Scope } from './scope';
import { closeSession, makeSession, updateSession } from './session';
import { SDK_VERSION } from './version';

/**
* API compatibility version of this hub.
Expand All @@ -35,7 +36,7 @@ import { closeSession, makeSession, updateSession } from './session';
*
* @hidden
*/
export const API_VERSION = 4;
export const API_VERSION = parseFloat(SDK_VERSION);

/**
* Default maximum number of breadcrumbs added to an event. Can be overwritten
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ Sentry.init({
tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production!
});

export function handleError(error: unknown, { request }: DataFunctionArgs): void {
Sentry.captureRemixServerException(error, 'remix.server', request);
}
export const handleError = Sentry.wrapRemixHandleError;

export default function handleRequest(
request: Request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ Sentry.init({
tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production!
});

export function handleError(error: unknown, { request }: DataFunctionArgs): void {
Sentry.captureRemixServerException(error, 'remix.server', request);
}
export const handleError = Sentry.wrapRemixHandleError;

export default function handleRequest(
request: Request,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NextResponse } from 'next/server';

export async function GET() {
return NextResponse.json({ result: 'static response' });
}

// This export makes it so that this route is always dynamically rendered (i.e Sentry will trace)
export const revalidate = 0;

// This export makes it so that this route will throw an error if the Request object is accessed in some way.
export const dynamic = 'error';
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,10 @@ test.describe('Edge runtime', () => {
expect(routehandlerError.contexts?.runtime?.name).toBe('vercel-edge');
});
});

test('should not crash route handlers that are configured with `export const dynamic = "error"`', async ({
request,
}) => {
const response = await request.get('/route-handlers/static');
expect(await response.json()).toStrictEqual({ result: 'static response' });
});
9 changes: 3 additions & 6 deletions packages/nextjs/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,19 @@ export type ServerComponentContext = {
};

export interface RouteHandlerContext {
// TODO(v8): Remove
/**
* @deprecated The SDK will automatically pick up the method from the incoming Request object instead.
*/
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
parameterizedRoute: string;
// TODO(v8): Remove
/**
* @deprecated The SDK will automatically pick up the `sentry-trace` header from the incoming Request object instead.
* @deprecated pass a complete `Headers` object with the `headers` field instead.
*/
sentryTraceHeader?: string;
// TODO(v8): Remove
/**
* @deprecated The SDK will automatically pick up the `baggage` header from the incoming Request object instead.
* @deprecated pass a complete `Headers` object with the `headers` field instead.
*/
baggageHeader?: string;
headers?: WebFetchHeaders;
}

export type VercelCronsConfig = { path?: string; schedule?: string }[] | undefined;
Expand Down
21 changes: 8 additions & 13 deletions packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { addTracingExtensions, captureException, flush, getCurrentHub, runWithAsyncContext, trace } from '@sentry/core';
import { tracingContextFromHeaders, winterCGRequestToRequestData } from '@sentry/utils';
import { tracingContextFromHeaders, winterCGHeadersToDict } from '@sentry/utils';

import { isRedirectNavigationError } from './nextNavigationErrorUtils';
import type { RouteHandlerContext } from './types';
Expand All @@ -15,23 +15,16 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
): (...args: Parameters<F>) => ReturnType<F> extends Promise<unknown> ? ReturnType<F> : Promise<ReturnType<F>> {
addTracingExtensions();
// eslint-disable-next-line deprecation/deprecation
const { method, parameterizedRoute, baggageHeader, sentryTraceHeader } = context;
const { method, parameterizedRoute, baggageHeader, sentryTraceHeader, headers } = context;
return new Proxy(routeHandler, {
apply: (originalFunction, thisArg, args) => {
return runWithAsyncContext(async () => {
const hub = getCurrentHub();
const currentScope = hub.getScope();

let req: Request | undefined;
let reqMethod: string | undefined;
if (args[0] instanceof Request) {
req = args[0];
reqMethod = req.method;
}

const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
sentryTraceHeader,
baggageHeader,
sentryTraceHeader ?? headers?.get('sentry-trace') ?? undefined,
baggageHeader ?? headers?.get('baggage'),
);
currentScope.setPropagationContext(propagationContext);

Expand All @@ -40,11 +33,13 @@ export function wrapRouteHandlerWithSentry<F extends (...args: any[]) => any>(
res = await trace(
{
op: 'http.server',
name: `${reqMethod ?? method} ${parameterizedRoute}`,
name: `${method} ${parameterizedRoute}`,
status: 'ok',
...traceparentData,
metadata: {
request: req ? winterCGRequestToRequestData(req) : undefined,
request: {
headers: headers ? winterCGHeadersToDict(headers) : undefined,
},
source: 'route',
dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as Sentry from '@sentry/nextjs';
import type { WebFetchHeaders } from '@sentry/types';
// @ts-expect-error Because we cannot be sure if the RequestAsyncStorage module exists (it is not part of the Next.js public
// API) we use a shim if it doesn't exist. The logic for this is in the wrapping loader.
import { requestAsyncStorage } from '__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__';
Expand Down Expand Up @@ -34,12 +35,14 @@ function wrapHandler<T>(handler: T, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | '
apply: (originalFunction, thisArg, args) => {
let sentryTraceHeader: string | undefined | null = undefined;
let baggageHeader: string | undefined | null = undefined;
let headers: WebFetchHeaders | undefined = undefined;

// We try-catch here just in case the API around `requestAsyncStorage` changes unexpectedly since it is not public API
try {
const requestAsyncStore = requestAsyncStorage.getStore();
sentryTraceHeader = requestAsyncStore?.headers.get('sentry-trace') ?? undefined;
baggageHeader = requestAsyncStore?.headers.get('baggage') ?? undefined;
headers = requestAsyncStore?.headers;
} catch (e) {
/** empty */
}
Expand All @@ -50,6 +53,7 @@ function wrapHandler<T>(handler: T, method: 'GET' | 'POST' | 'PUT' | 'PATCH' | '
parameterizedRoute: '__ROUTE__',
sentryTraceHeader,
baggageHeader,
headers,
}).apply(thisArg, args);
},
});
Expand Down
19 changes: 19 additions & 0 deletions packages/nextjs/src/config/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ let showedMissingOrgSlugErrorMsg = false;
let showedMissingProjectSlugErrorMsg = false;
let showedHiddenSourceMapsWarningMsg = false;
let showedMissingCliBinaryWarningMsg = false;
let showedMissingGlobalErrorWarningMsg = false;

// TODO: merge default SentryWebpackPlugin ignore with their SentryWebpackPlugin ignore or ignoreFile
// TODO: merge default SentryWebpackPlugin include with their SentryWebpackPlugin include
Expand Down Expand Up @@ -328,6 +329,24 @@ export function constructWebpackConfigFunction(
});
}

if (appDirPath) {
const hasGlobalErrorFile = ['global-error.js', 'global-error.jsx', 'global-error.ts', 'global-error.tsx'].some(
globalErrorFile => fs.existsSync(path.join(appDirPath!, globalErrorFile)),
);

if (!hasGlobalErrorFile && !showedMissingGlobalErrorWarningMsg) {
// eslint-disable-next-line no-console
console.log(
`${chalk.yellow(
'warn',
)} - It seems like you don't have a global error handler set up. It is recommended that you add a ${chalk.cyan(
'global-error.js',
)} file with Sentry instrumentation so that React rendering errors are reported to Sentry. Read more: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#react-render-errors-in-app-router`,
);
showedMissingGlobalErrorWarningMsg = true;
}
}

// The SDK uses syntax (ES6 and ES6+ features like object spread) which isn't supported by older browsers. For users
// who want to support such browsers, `transpileClientSDK` allows them to force the SDK code to go through the same
// transpilation that their code goes through. We don't turn this on by default because it increases bundle size
Expand Down
4 changes: 2 additions & 2 deletions packages/node/src/integrations/spotlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export class Spotlight implements Integration {
* Sets up forwarding envelopes to the Spotlight Sidecar
*/
public setup(client: Client): void {
if (process.env.NODE_ENV !== 'development') {
logger.warn("[Spotlight] It seems you're not in dev mode. Do you really want to have Spoltight enabled?");
if (typeof process === 'object' && process.env && process.env.NODE_ENV !== 'development') {
logger.warn("[Spotlight] It seems you're not in dev mode. Do you really want to have Spotlight enabled?");
}
connectToSpotlight(client, this._options);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ export function getSentryRelease(fallback?: string): string | undefined {
process.env.ZEIT_GITHUB_COMMIT_SHA ||
process.env.ZEIT_GITLAB_COMMIT_SHA ||
process.env.ZEIT_BITBUCKET_COMMIT_SHA ||
// Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables
process.env.CF_PAGES_COMMIT_SHA ||
fallback
);
}
Expand Down
36 changes: 34 additions & 2 deletions packages/node/test/integrations/spotlight.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ describe('Spotlight', () => {
integration.setup(client);

expect(loggerSpy).toHaveBeenCalledWith(
expect.stringContaining("It seems you're not in dev mode. Do you really want to have Spoltight enabled?"),
expect.stringContaining("It seems you're not in dev mode. Do you really want to have Spotlight enabled?"),
);

process.env.NODE_ENV = oldEnvValue;
Expand All @@ -152,9 +152,41 @@ describe('Spotlight', () => {
integration.setup(client);

expect(loggerSpy).not.toHaveBeenCalledWith(
expect.stringContaining("It seems you're not in dev mode. Do you really want to have Spoltight enabled?"),
expect.stringContaining("It seems you're not in dev mode. Do you really want to have Spotlight enabled?"),
);

process.env.NODE_ENV = oldEnvValue;
});

it('handles `process` not being available', () => {
const originalProcess = process;

// @ts-expect-error - TS complains but we explicitly wanna test this
delete global.process;

const integration = new Spotlight({ sidecarUrl: 'http://localhost:8969' });
integration.setup(client);

expect(loggerSpy).not.toHaveBeenCalledWith(
expect.stringContaining("It seems you're not in dev mode. Do you really want to have Spotlight enabled?"),
);

global.process = originalProcess;
});

it('handles `process.env` not being available', () => {
const originalEnv = process.env;

// @ts-expect-error - TS complains but we explicitly wanna test this
delete process.env;

const integration = new Spotlight({ sidecarUrl: 'http://localhost:8969' });
integration.setup(client);

expect(loggerSpy).not.toHaveBeenCalledWith(
expect.stringContaining("It seems you're not in dev mode. Do you really want to have Spotlight enabled?"),
);

process.env = originalEnv;
});
});
2 changes: 1 addition & 1 deletion packages/remix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"access": "public"
},
"dependencies": {
"@sentry/cli": "^2.21.2",
"@sentry/cli": "^2.22.3",
"@sentry/core": "7.85.0",
"@sentry/node": "7.85.0",
"@sentry/react": "7.85.0",
Expand Down
Loading
Loading