UNPKG

@sentry/nextjs

Version:
218 lines (215 loc) 11 kB
import { HTTP_TARGET, URL_QUERY } from '@sentry/conventions/attributes'; import { GLOBAL_OBJ, debug, applySdkMetadata, getGlobalScope, getClient, SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core'; import { experimentalUseDiagnosticsChannelInjection as experimentalUseDiagnosticsChannelInjection$1, getDefaultIntegrations, httpIntegration, isDiagnosticsChannelInjectionEnabled, init as init$1 } from '@sentry/node'; export * from '@sentry/node'; export { pinoIntegration } from '@sentry/node'; import { DEBUG_BUILD } from '../common/debug-build.js'; import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor.js'; import { getVercelEnv } from '../common/getVercelEnv.js'; import { TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION } from '../common/span-attributes-with-logic-attached.js'; import { isBuild } from '../common/utils/isBuild.js'; import { isCloudflareWaitUntilAvailable } from '../common/utils/responseEnd.js'; import { setUrlProcessingMetadata } from '../common/utils/setUrlProcessingMetadata.js'; import { distDirRewriteFramesIntegration } from './distDirRewriteFramesIntegration.js'; import { enhanceMiddlewareRootSpan } from '../common/enhanceMiddlewareRootSpan.js'; import { enhanceHandleRequestRootSpan } from './enhanceHandleRequestRootSpan.js'; import { handleOnSpanStart } from './handleOnSpanStart.js'; import { prepareSafeIdGeneratorContext } from './prepareSafeIdGeneratorContext.js'; import { maybeCompleteCronCheckIn } from './vercelCronsMonitoring.js'; import { maybeCleanupQueueSpan } from './vercelQueuesMonitoring.js'; export { captureUnderscoreErrorException } from '../common/pages-router-instrumentation/_error.js'; export { startInactiveSpan, startSpan, startSpanManual } from '../common/utils/nextSpan.js'; export { wrapGetStaticPropsWithSentry } from '../common/pages-router-instrumentation/wrapGetStaticPropsWithSentry.js'; export { wrapGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapGetInitialPropsWithSentry.js'; export { wrapAppGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapAppGetInitialPropsWithSentry.js'; export { wrapDocumentGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapDocumentGetInitialPropsWithSentry.js'; export { wrapErrorGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapErrorGetInitialPropsWithSentry.js'; export { wrapGetServerSidePropsWithSentry } from '../common/pages-router-instrumentation/wrapGetServerSidePropsWithSentry.js'; export { wrapServerComponentWithSentry } from '../common/wrapServerComponentWithSentry.js'; export { wrapRouteHandlerWithSentry } from '../common/wrapRouteHandlerWithSentry.js'; export { wrapApiHandlerWithSentryVercelCrons } from '../common/pages-router-instrumentation/wrapApiHandlerWithSentryVercelCrons.js'; export { wrapMiddlewareWithSentry } from '../common/wrapMiddlewareWithSentry.js'; export { wrapPageComponentWithSentry } from '../common/pages-router-instrumentation/wrapPageComponentWithSentry.js'; export { wrapGenerationFunctionWithSentry } from '../common/wrapGenerationFunctionWithSentry.js'; export { withServerActionInstrumentation } from '../common/withServerActionInstrumentation.js'; export { captureRequestError } from '../common/captureRequestError.js'; export { wrapApiHandlerWithSentry } from '../common/pages-router-instrumentation/wrapApiHandlerWithSentry.js'; const globalWithInjectedValues = GLOBAL_OBJ; function experimentalUseDiagnosticsChannelInjection() { const tracingHooksDir = process.env._sentryOrchestrionTracingHooksDir || globalWithInjectedValues._sentryOrchestrionTracingHooksDir; experimentalUseDiagnosticsChannelInjection$1(tracingHooksDir ? { tracingHooksDir } : void 0); } prepareSafeIdGeneratorContext(); const ErrorBoundary = (props) => { if (!props.children) { return null; } if (typeof props.children === "function") { return props.children(); } return props.children; }; function createReduxEnhancer() { return (createStore) => createStore; } function withErrorBoundary(WrappedComponent) { return WrappedComponent; } function showReportDialog() { return; } function getCloudflareRuntimeConfig() { if (isCloudflareWaitUntilAvailable()) { return { runtime: { name: "cloudflare" } }; } return void 0; } function init(options) { prepareSafeIdGeneratorContext(); if (isBuild()) { return; } if (!DEBUG_BUILD && options.debug) { console.warn( "[@sentry/nextjs] You have enabled `debug: true`, but Sentry debug logging was removed from your bundle (likely via `withSentryConfig({ disableLogger: true })` / `webpack.treeshake.removeDebugLogging: true`). Set that option to `false` to see Sentry debug output." ); } const customDefaultIntegrations = getDefaultIntegrations(options).filter((integration) => integration.name !== "Http").concat( // We are using the HTTP integration without instrumenting incoming HTTP requests because Next.js does that by itself. httpIntegration({ disableIncomingRequestSpans: true }) ); if (!options.skipOpenTelemetrySetup) { process.env.NEXT_OTEL_FETCH_DISABLED = "1"; } const distDirName = process.env._sentryRewriteFramesDistDir || globalWithInjectedValues._sentryRewriteFramesDistDir; if (distDirName) { customDefaultIntegrations.push(distDirRewriteFramesIntegration({ distDirName })); } const useDiagnosticsChannelInjection = process.env._sentryUseDiagnosticsChannelInjection || globalWithInjectedValues._sentryUseDiagnosticsChannelInjection; if (DEBUG_BUILD && useDiagnosticsChannelInjection && !isDiagnosticsChannelInjectionEnabled()) { debug.warn( "[@sentry/nextjs] `useDiagnosticsChannelInjection` is enabled in `withSentryConfig`, but `Sentry.experimentalUseDiagnosticsChannelInjection()` was not called before `Sentry.init()`. Server DB spans will not be recorded." ); } const cloudflareConfig = getCloudflareRuntimeConfig(); const opts = { environment: options.environment || process.env.SENTRY_ENVIRONMENT || getVercelEnv(false) || process.env.NODE_ENV, release: process.env._sentryRelease || globalWithInjectedValues._sentryRelease, defaultIntegrations: customDefaultIntegrations, ...options, // Override runtime to 'cloudflare' when running on OpenNext/Cloudflare ...cloudflareConfig }; const nextjsIgnoreSpans = [ // Static assets (matches `_next/static` anywhere in the name to handle custom basePath) /^GET (\/.*)?\/_next\/static\//, // Dev source-map fetch endpoints /\/__nextjs_original-stack-frame/, // Pages router /404 /^\/404$/, // App router /404 and /_not-found segments (any HTTP method) /^(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH) \/(404|_not-found)$/, // Next.js 13 root transactions named "NextServer.getRequestHandler" containing useless tracing /^NextServer\.getRequestHandler$/, // Spans flagged via TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION // (set in `dropMiddlewareTunnelRequests` during `spanStart`) { attributes: { [TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION]: true } } ]; opts.ignoreSpans = [...opts.ignoreSpans || [], ...nextjsIgnoreSpans]; if (DEBUG_BUILD && opts.debug) { debug.enable(); } DEBUG_BUILD && debug.log("Initializing SDK..."); if (sdkAlreadyInitialized()) { DEBUG_BUILD && debug.log("SDK already initialized"); return; } applySdkMetadata(opts, "nextjs", ["nextjs", cloudflareConfig ? "cloudflare" : "node"]); const client = init$1(opts); client?.on("beforeSampling", ({ spanAttributes }, samplingDecision) => { if ( // eslint-disable-next-line typescript/no-deprecated typeof spanAttributes[HTTP_TARGET] === "string" && // eslint-disable-next-line typescript/no-deprecated spanAttributes[HTTP_TARGET].includes("sentry_key") && // eslint-disable-next-line typescript/no-deprecated spanAttributes[HTTP_TARGET].includes("sentry_client") || typeof spanAttributes[URL_QUERY] === "string" && spanAttributes[URL_QUERY].includes("sentry_key") && spanAttributes[URL_QUERY].includes("sentry_client") ) { samplingDecision.decision = false; } }); client?.on("spanStart", handleOnSpanStart); client?.on("spanEnd", maybeCompleteCronCheckIn); client?.on("spanEnd", maybeCleanupQueueSpan); getGlobalScope().addEventProcessor( Object.assign( ((event, hint) => { if (event.type !== void 0) { return event; } const originalException = hint.originalException; const isPostponeError = typeof originalException === "object" && originalException !== null && "$$typeof" in originalException && originalException.$$typeof === /* @__PURE__ */ Symbol.for("react.postpone"); if (isPostponeError) { return null; } const exceptionMessage = event.exception?.values?.[0]?.value; if (exceptionMessage?.includes("Suspense Exception: This is not a real error!") || exceptionMessage?.includes("Suspense Exception: This is not a real error, and should not leak")) { return null; } return event; }), { id: "DropReactControlFlowErrors" } ) ); client?.on("preprocessEvent", (event) => { if (event.type === "transaction" && event.contexts?.trace?.data) { const mutableRootSpan = { attributes: event.contexts.trace.data, getName: () => event.transaction, setName: (name) => { event.transaction = name; }, setOp: (op) => { event.contexts.trace.op = op; } }; enhanceHandleRequestRootSpan(mutableRootSpan); enhanceMiddlewareRootSpan(mutableRootSpan); } setUrlProcessingMetadata(event); }); client?.on("processSegmentSpan", (span) => { const attributes = span.attributes ?? (span.attributes = {}); const mutableRootSpan = { attributes, getName: () => span.name, setName: (name) => { span.name = name; }, // For streamed spans, op lives in `attributes['sentry.op']` - mirror it there so middleware // overrides land somewhere readable (the legacy path uses a separate `event.contexts.trace.op`). setOp: (op) => { attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] = op; } }; enhanceHandleRequestRootSpan(mutableRootSpan); enhanceMiddlewareRootSpan(mutableRootSpan); }); if (process.env.NODE_ENV === "development") { getGlobalScope().addEventProcessor(devErrorSymbolicationEventProcessor); } try { if (process.turbopack) { getGlobalScope().setTag("turbopack", true); getGlobalScope().setAttribute("turbopack", true); } } catch { } DEBUG_BUILD && debug.log("SDK successfully initialized"); return client; } function sdkAlreadyInitialized() { return !!getClient(); } export { ErrorBoundary, createReduxEnhancer, experimentalUseDiagnosticsChannelInjection, init, showReportDialog, withErrorBoundary }; //# sourceMappingURL=index.js.map