Skip to content

Stacktraces not source mapped after upgrading from 7.26 to 7.42 (Next.js assetPrefix) #7500

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

Closed
3 tasks done
eirikur-grid opened this issue Mar 17, 2023 · 4 comments · Fixed by #7619
Closed
3 tasks done
Labels
Package: nextjs Issues related to the Sentry Nextjs SDK

Comments

@eirikur-grid
Copy link

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using? If you use the CDN bundles, please specify the exact bundle (e.g. bundle.tracing.min.js) in your SDK setup.

@sentry/nextjs

SDK Version

7.42.0

Framework Version

Next.js 12.3.2

Link to Sentry event

https://grid.sentry.io/issues/3671197832/events/004e5ad1ed91484f92e601c6c5f13b83/?project=1871088

SDK Setup

Client config

Sentry.init({
  enabled: isEnabled,
  dsn: SENTRY_DSN,
  environment: SENTRY_ENV,
  release: BUILD_ID,
  ignoreErrors,
  beforeSend: event => {
    const { type, title, contexts } = event;
    if (type === 'error' &&
          /^(?:iPhone|Mac|iPad)$/.test(contexts?.device?.family || '') &&
          (
            /^TypeError: (?:cancelled|geannuleerd|cancelado|annulleret|avbrutt|avbruten|Abgebrochen)$/i.test(title || '')
          )) {
      return null;
    }

    integrateWithFullstory(event);
    return event;
  },
  integrations:  [
    new Integrations.BrowserTracing({
      tracingOrigins: [ getApiHost() ],
      beforeNavigate: context => {
        const dynamicRouteName = mapSlugToRoute(window.location.pathname);
        if (dynamicRouteName) {
          return {
            ...context, name: dynamicRouteName,
          };
        }
        return context;
      },
    }),
  ]
    .filter(Boolean),
  tracesSampler: samplingRate,
});

Server config

import * as Sentry from '@sentry/nextjs';
Sentry.init({
  enabled: process.env.NODE_ENV === 'production',
  environment: SENTRY_ENV,
  dsn: SENTRY_DSN,
  release: BUILD_ID,
  tracesSampleRate: 0,
});

Steps to Reproduce

We recently updated the following sentry packages from version 7.26 to 7.42:

  • @sentry/nextjs
  • @sentry/tracing
  • @sentry/utils

We have a Next.js application that has an asset prefix defined as /_client
The sourcemaps are uploaded to Sentry at build time from CircleCI. The source maps are not included in the docker image that we then later deploy.

Expected Result

Stack traces show original, unminified JavaScript/TypeScript code.

Actual Result

Stack traces show minified code.

Using the sentry-cli tool to investigate, it appears as if the assetPrefix is causing a mismatch.
Screenshot 2023-03-16 at 17 03 07

We have downgraded back to 7.26 and can verify that source maps are working again after doing so.

@Meemaw
Copy link

Meemaw commented Mar 17, 2023

Having similar issues as well.

@Lms24 Lms24 added the Package: nextjs Issues related to the Sentry Nextjs SDK label Mar 20, 2023
@lforst
Copy link
Contributor

lforst commented Mar 20, 2023

Hi, can you share your next.config.js? thanks!

@eirikur-grid
Copy link
Author

Here it is

/* globals module require process __dirname */
const path = require('path');
const { DefinePlugin, IgnorePlugin } = require('webpack');
const { withSentryConfig } = require('@sentry/nextjs');

// As an exception to the general rule of not transpiling anything under node_modules
// we transpile these modules that do not provide the same level of browser support.
const withTM = require('next-transpile-modules')([
  '@grid-is/apiary',
  '@borgar/fx',
  'antlr4',
]);

let gitHash;
/* git hash determination omitted */

let gitBranch;
/* git branch determination omitted */

const runDate = new Date()
  .toDateString()
  .split(' ')
  .slice(1, 3)
  .join('-')
  .toLowerCase();
const buildId = runDate + ':' + gitHash;

const assetPrefix = process.env.ASSET_PREFIX || '';

const sendSourceMaps =
  (gitBranch === 'develop' || gitBranch === 'master');
  /* other conditions omitted */

const SentryWebpackPluginOptions = {
  release: buildId,
  include: '.next',
  setCommits: {
    auto: true,
  },
  silent: false,
  // For all available options, see:
  // https://github.com/getsentry/sentry-webpack-plugin#options.
};
const moduleExports = {
  // strict mode is a development mode only feature for highlighting potential problems in an application
  // see https://nextjs.org/docs/api-reference/next.config.js/react-strict-mode for more info
  // reactStrictMode: true,
  sentry: {
    disableServerWebpackPlugin: !sendSourceMaps,
    disableClientWebpackPlugin: !sendSourceMaps,
  },
  outputFileTracing: false, // workaround for https://github.com/getsentry/sentry-javascript/issues/4103
  serverRuntimeConfig: {
    rootDir: __dirname,
    dynamicRendering: process.env.DYNAMIC_RENDERING,
  },
  sassOptions: {
    includePaths: [ path.join(__dirname, 'src', 'styles') ],
  },
  experimental: {
    esmExternals: 'loose',
  },
  async rewrites () {
    return [
      /* omitted */
    ];
  },
  async redirects () {
    return [
      /* omitted */
    ];
  },
  async headers () {
    return [
      {
        source: '/_next/static/wasm/:all*',
        locale: false,
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=31536001, immutable',
          },
        ],
      },
    ];
  },
  webpack: (config, { isServer, dev }) => {
    config.experiments.asyncWebAssembly = true;
    config.resolve.fallback = {
      ...config.resolve.fallback,
      fs: false,
    };

    // Be default, font filenames will have a hash appended to them.
    // That can make it tricky to reference them directly, e.g. for
    // preloading, because the URL might not be stable.
    // The following rule is intended to suppress that behavior.
    config.module.rules.push({
      test: /\.(woff(2)?|ttf|eot)$/,
      type: 'asset/resource',
      generator: {
        filename: './static/media/fonts/[name][ext]',
      },
    });

    let sentryEnv;
    // HACK: presume that development is exclusive to computers running MacOS
    // XXX: read the sentry environment from an environment variable
    if (dev || process.platform === 'darwin') {
      sentryEnv = 'localdev';
    }
    else if (gitBranch === 'master') {
      sentryEnv = 'production';
    }
    else if (gitBranch === 'develop') {
      sentryEnv = 'staging';
    }
    else {
      sentryEnv = 'branch-deployment';
    }
    // Workaround https://github.com/oguimbal/pg-mem/issues/225
    config.plugins.push(
      new IgnorePlugin({
        resourceRegExp: /^@mikro-orm\/|^knex|typeorm|slonik|pg-promise/,
        contextRegExp: /pg-mem/,
      }),
    );
    config.plugins.push(
      new DefinePlugin({
        SENTRY_ENV: `"${sentryEnv}"`,
        /* others redacted */
      }),
    );

    return config;
  },
};

if (assetPrefix) {
  moduleExports.assetPrefix = assetPrefix;
}

/**
 * @param {string} phase
 * @param {{ defaultConfig: import("@sentry/nextjs/types/config/types").NextConfigObject; }} defaults
 * @returns {import('@sentry/nextjs/types/config/types').NextConfigObject}
 */
module.exports = (phase, defaults) => {
  const sentryConfig = withSentryConfig(
    moduleExports,
    SentryWebpackPluginOptions,
  );

  // Here sentryConfig is either a config object or a function that returns one.
  // If it is a function, we must call that function, because the subsequent
  // config modifiers `withTM` and `withBundleAnalyzer` both assume they get a
  // config object, not a function (and if they do get a function, they don't
  // notice, and just treat it like a blank configuration object, yielding
  // oh-so-confusing build failures.)

  /** @type {import('next').NextConfig} */
  let config;
  if (typeof sentryConfig === 'function') {
    config = sentryConfig(phase, defaults);
  }
  else {
    config = sentryConfig;
  }

  config = withTM(config);

  if (process.env.ANALYZE === 'true') {
    const withBundleAnalyzer = require('@next/bundle-analyzer')({
      enabled: true,
    });
    config = withBundleAnalyzer(config);
  }

  return config;
};

@lforst
Copy link
Contributor

lforst commented Mar 27, 2023

Thanks, this was a regression and we have identified the cause. A fix is on its way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Package: nextjs Issues related to the Sentry Nextjs SDK
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants