Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion packages/nextjs/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { RequestAsyncStorage } from '../config/templates/requestAsyncStorag

export type ServerComponentContext = {
componentRoute: string;
componentType: string;
componentType: 'Page' | 'Layout' | 'Head' | 'Not-found' | 'Loading' | 'Unknown';
headers?: WebFetchHeaders;
};

Expand Down
82 changes: 43 additions & 39 deletions packages/nextjs/src/common/wrapServerComponentWithSentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
handleCallbackErrors,
startSpanManual,
withIsolationScope,
withScope,
} from '@sentry/core';
import { propagationContextFromHeaders, winterCGHeadersToDict } from '@sentry/utils';

Expand Down Expand Up @@ -55,47 +56,50 @@ export function wrapServerComponentWithSentry<F extends (...args: any[]) => any>
const propagationContext = commonObjectToPropagationContext(context.headers, incomingPropagationContext);

return withIsolationScope(isolationScope, () => {
isolationScope.setTransactionName(`${componentType} Server Component (${componentRoute})`);
getCurrentScope().setPropagationContext(propagationContext);
return startSpanManual(
{
op: 'function.nextjs',
name: `${componentType} Server Component (${componentRoute})`,
forceTransaction: true,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs',
},
},
span => {
return handleCallbackErrors(
() => originalFunction.apply(thisArg, args),
error => {
if (isNotFoundNavigationError(error)) {
// We don't want to report "not-found"s
span.setStatus({ code: SPAN_STATUS_ERROR, message: 'not_found' });
} else if (isRedirectNavigationError(error)) {
// We don't want to report redirects
span.setStatus({ code: SPAN_STATUS_OK });
} else {
span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
captureException(error, {
mechanism: {
handled: false,
},
});
}
},
() => {
span.end();
withScope(scope => {
scope.setTransactionName(`${componentType} Server Component (${componentRoute})`);

// flushQueue should not throw
// eslint-disable-next-line @typescript-eslint/no-floating-promises
flushQueue();
getCurrentScope().setPropagationContext(propagationContext);
return startSpanManual(
{
op: 'function.nextjs',
name: `${componentType} Server Component (${componentRoute})`,
forceTransaction: true,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component',
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs',
},
);
},
);
},
span => {
return handleCallbackErrors(
() => originalFunction.apply(thisArg, args),
error => {
if (isNotFoundNavigationError(error)) {
// We don't want to report "not-found"s
span.setStatus({ code: SPAN_STATUS_ERROR, message: 'not_found' });
} else if (isRedirectNavigationError(error)) {
// We don't want to report redirects
span.setStatus({ code: SPAN_STATUS_OK });
} else {
span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
captureException(error, {
mechanism: {
handled: false,
},
});
}
},
() => {
span.end();

// flushQueue should not throw
// eslint-disable-next-line @typescript-eslint/no-floating-promises
flushQueue();
},
);
},
);
});
});
});
},
Expand Down
4 changes: 2 additions & 2 deletions packages/nextjs/src/config/loaders/wrappingLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as chalk from 'chalk';
import type { RollupBuild, RollupError } from 'rollup';
import { rollup } from 'rollup';

import type { VercelCronsConfig } from '../../common/types';
import type { ServerComponentContext, VercelCronsConfig } from '../../common/types';
import type { LoaderThis } from './types';

// Just a simple placeholder to make referencing module consistent
Expand Down Expand Up @@ -185,7 +185,7 @@ export default function wrappingLoader(
.match(/\/?([^/]+)\.(?:js|ts|jsx|tsx)$/);

if (componentTypeMatch && componentTypeMatch[1]) {
let componentType;
let componentType: ServerComponentContext['componentType'];
switch (componentTypeMatch[1]) {
case 'page':
componentType = 'Page';
Expand Down